From 59b633c20b047b9b5d74e044496033754960305c Mon Sep 17 00:00:00 2001 From: Cindy Alvarez Date: Thu, 12 Nov 2020 17:17:24 -0800 Subject: [PATCH 01/65] Update types-of-emails-github-sends.md - Added research emails to intro & added a section --- .../types-of-emails-github-sends.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md b/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md index eca5d3f1b2..f6645076ab 100644 --- a/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md +++ b/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md @@ -1,6 +1,6 @@ --- title: Types of emails GitHub sends -intro: 'There are several types of emails you can receive from {% data variables.product.product_name %}, including notifications, account information, and marketing communications.' +intro: 'There are several types of emails you can receive from {% data variables.product.product_name %}, including notifications, account information, customer research invitations, and marketing communications.' redirect_from: - /articles/types-of-emails-github-sends versions: @@ -25,6 +25,17 @@ You can also choose which type of email updates you'd like to receive on convers If you've upgraded to paid products or features, then you'll receive billing receipts at the account's primary email address. For more information, see "[Setting your billing email](/articles/setting-your-billing-email)." +### Customer research emails + +{% data variables.product.product_name %} occasionally seeks customers to participate in research sessions to help us build a better GitHub. These are conducted remotely, open to customers worldwide, and may include: + +- Feedback surveys +- Research interviews +- Usability testing sessions +- Previewing early prototypes or concepts + +These emails are infrequent and you can choose whether or not to participate. If you're interested in additional opportunities to participate in research sessions, you may add yourself to the [GitHub Customer Research Panel](https://cxr.github.com). + ### Marketing emails {% data variables.product.product_name %} occasionally sends these types of marketing emails: From 237c3bf7093183686da08a4d56e16b3782a30c83 Mon Sep 17 00:00:00 2001 From: szunami Date: Wed, 9 Dec 2020 12:03:38 -0500 Subject: [PATCH 02/65] Add info on where posts are published to When following this tutorial, I found it very difficult to actually view the post I just created. The default behavior is documented here: https://jekyllrb.com/docs/front-matter/#predefined-global-variables --- .../adding-content-to-your-github-pages-site-using-jekyll.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/github/working-with-github-pages/adding-content-to-your-github-pages-site-using-jekyll.md b/content/github/working-with-github-pages/adding-content-to-your-github-pages-site-using-jekyll.md index 31bdf54231..26e7f87d19 100644 --- a/content/github/working-with-github-pages/adding-content-to-your-github-pages-site-using-jekyll.md +++ b/content/github/working-with-github-pages/adding-content-to-your-github-pages-site-using-jekyll.md @@ -62,6 +62,8 @@ Your theme includes default layouts, includes, and stylesheets that will automat {% data reusables.files.choose_commit_branch %} {% data reusables.files.propose_file_change %} +Your post should now be up on your site! If the base URL of your site is `https://octocat.github.io`, then your new post will be located at `https://octocat.github.io/YYYY/MM/DD/TITLE.html`. + ### Next steps {% data reusables.pages.add-jekyll-theme %} For more information, see "[Adding a theme to your {% data variables.product.prodname_pages %} site using Jekyll](/articles/adding-a-theme-to-your-github-pages-site-using-jekyll)." From ea92d43128e3c7a2558659801d2cdba31f77c871 Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Wed, 6 Jan 2021 12:54:24 +0100 Subject: [PATCH 03/65] Correct curl params to match output in examples --- .../rest/overview/resources-in-the-rest-api.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/content/rest/overview/resources-in-the-rest-api.md b/content/rest/overview/resources-in-the-rest-api.md index 062ccc1e80..812762ce3b 100644 --- a/content/rest/overview/resources-in-the-rest-api.md +++ b/content/rest/overview/resources-in-the-rest-api.md @@ -31,7 +31,7 @@ For information about GitHub's GraphQL API, see the [v4 documentation](/graphql) sent and received as JSON. ```shell -$ curl -i {% data variables.product.api_url_pre %}/users/octocat/orgs +$ curl -I {% data variables.product.api_url_pre %}/users/octocat/orgs > HTTP/1.1 200 OK > Server: nginx @@ -137,7 +137,7 @@ Read [more about unauthenticated rate limiting](#increasing-the-unauthenticated- Authenticating with invalid credentials will return `401 Unauthorized`: ```shell -$ curl -i {% data variables.product.api_url_pre %} -u foo:bar +$ curl -I {% data variables.product.api_url_pre %} -u foo:bar > HTTP/1.1 401 Unauthorized > { @@ -369,7 +369,7 @@ Note that [the Search API has custom rate limit rules](/rest/reference/search#ra The returned HTTP headers of any API request show your current rate limit status: ```shell -$ curl -i {% data variables.product.api_url_pre %}/users/octocat +$ curl -I {% data variables.product.api_url_pre %}/users/octocat > HTTP/1.1 200 OK > Date: Mon, 01 Jul 2013 17:27:06 GMT > Status: 200 OK @@ -469,7 +469,7 @@ User-Agent: Awesome-Octocat-App cURL sends a valid `User-Agent` header by default. If you provide an invalid `User-Agent` header via cURL (or via an alternative client), you will receive a `403 Forbidden` response: ```shell -$ curl -iH 'User-Agent: ' {% data variables.product.api_url_pre %}/meta +$ curl -IH 'User-Agent: ' {% data variables.product.api_url_pre %}/meta > HTTP/1.0 403 Forbidden > Connection: close > Content-Type: text/html @@ -501,7 +501,7 @@ whenever possible. {% endif %} ```shell -$ curl -i {% data variables.product.api_url_pre %}/user +$ curl -I {% data variables.product.api_url_pre %}/user > HTTP/1.1 200 OK > Cache-Control: private, max-age=60 > ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" @@ -512,7 +512,7 @@ $ curl -i {% data variables.product.api_url_pre %}/user > X-RateLimit-Remaining: 4996 > X-RateLimit-Reset: 1372700873 -$ curl -i {% data variables.product.api_url_pre %}/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"' +$ curl -I {% data variables.product.api_url_pre %}/user -H 'If-None-Match: "644b5b0155e6404a9cc4bd9d8b1ae730"' > HTTP/1.1 304 Not Modified > Cache-Control: private, max-age=60 > ETag: "644b5b0155e6404a9cc4bd9d8b1ae730" @@ -523,7 +523,7 @@ $ curl -i {% data variables.product.api_url_pre %}/user -H 'If-None-Match: "644b > X-RateLimit-Remaining: 4996 > X-RateLimit-Reset: 1372700873 -$ curl -i {% data variables.product.api_url_pre %}/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT" +$ curl -I {% data variables.product.api_url_pre %}/user -H "If-Modified-Since: Thu, 05 Jul 2012 15:31:30 GMT" > HTTP/1.1 304 Not Modified > Cache-Control: private, max-age=60 > Last-Modified: Thu, 05 Jul 2012 15:31:30 GMT @@ -546,7 +546,7 @@ Here's a sample request sent from a browser hitting `http://example.com`: ```shell -$ curl -i {% data variables.product.api_url_pre %} -H "Origin: http://example.com" +$ curl -I {% data variables.product.api_url_pre %} -H "Origin: http://example.com" HTTP/1.1 302 Found Access-Control-Allow-Origin: * Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval @@ -555,7 +555,7 @@ Access-Control-Expose-Headers: ETag, Link, X-GitHub-OTP, X-RateLimit-Limit, X-Ra This is what the CORS preflight request looks like: ```shell -$ curl -i {% data variables.product.api_url_pre %} -H "Origin: http://example.com" -X OPTIONS +$ curl -I {% data variables.product.api_url_pre %} -H "Origin: http://example.com" -X OPTIONS HTTP/1.1 204 No Content Access-Control-Allow-Origin: * Access-Control-Allow-Headers: Authorization, Content-Type, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, X-GitHub-OTP, X-Requested-With From 2aa39579678b74d99402747eff0aa154e7979c30 Mon Sep 17 00:00:00 2001 From: Eli Perkins Date: Thu, 7 Jan 2021 10:52:38 -0500 Subject: [PATCH 04/65] Add missing closing bracket to mutation structure I noticed this was missing a balanced bracket! --- content/graphql/guides/forming-calls-with-graphql.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/graphql/guides/forming-calls-with-graphql.md b/content/graphql/guides/forming-calls-with-graphql.md index 6fe661656f..4a826e8d0e 100644 --- a/content/graphql/guides/forming-calls-with-graphql.md +++ b/content/graphql/guides/forming-calls-with-graphql.md @@ -103,6 +103,7 @@ Mutations are structured like this:
mutation {
   mutationName(input: {MutationNameInput!}) {
     MutationNamePayload
+  }
 }
The input object in this example is `MutationNameInput`, and the payload object is `MutationNamePayload`. From 33f93e39c73ce024ef39aefd2658bb0f8b83f98f Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 7 Jan 2021 13:14:44 -0500 Subject: [PATCH 05/65] remove overloaded helper functions and move code directly where it is used --- lib/all-products.js | 3 +- lib/all-versions.js | 2 +- lib/find-page-in-version.js | 22 ----- lib/find-page.js | 69 --------------- lib/liquid-tags/link.js | 15 ++-- lib/path-utils.js | 87 +++---------------- lib/permalink.js | 4 +- .../get-docs-path-from-developer-path.js | 4 +- lib/redirects/get-old-paths-from-permalink.js | 21 +++-- lib/redirects/permalinks.js | 9 +- lib/redirects/precompile.js | 24 ----- lib/remove-fpt-from-path.js | 11 +++ lib/rewrite-local-links.js | 43 +++++++-- lib/site-tree.js | 60 ++++++------- middleware/archived-enterprise-versions.js | 3 +- middleware/breadcrumbs.js | 17 +++- middleware/contextualizers/rest.js | 12 +-- middleware/featured-links.js | 11 ++- tests/helpers/links-checker.js | 7 +- 19 files changed, 158 insertions(+), 266 deletions(-) delete mode 100644 lib/find-page-in-version.js delete mode 100644 lib/find-page.js create mode 100644 lib/remove-fpt-from-path.js diff --git a/lib/all-products.js b/lib/all-products.js index f65a8a11be..e56ffc21b3 100644 --- a/lib/all-products.js +++ b/lib/all-products.js @@ -7,6 +7,7 @@ const yaml = require('js-yaml') const contentDir = path.join(process.cwd(), 'content') const frontmatter = require('@github-docs/frontmatter') const getApplicableVersions = require('./get-applicable-versions') +const removeFPTFromPath = require('./remove-fpt-from-path') // the product order is determined by data/products.yml const productsFile = path.join(process.cwd(), 'data/products.yml') @@ -46,7 +47,7 @@ sortedProductIds.forEach(productId => { const toc = slash(path.join(dir, 'index.md')) const { data } = frontmatter(fs.readFileSync(toc, 'utf8')) const applicableVersions = getApplicableVersions(data.versions, toc) - const href = slash(path.join('/', applicableVersions[0], productId)) + const href = removeFPTFromPath(`/${applicableVersions[0]}/${productId}`) internalProducts[productId] = { id: productId, diff --git a/lib/all-versions.js b/lib/all-versions.js index 8af27e1e3f..083a1b26cc 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -9,7 +9,7 @@ const latestNonNumberedRelease = 'latest' const plans = [ { plan: 'free-pro-team', - planTitle: 'Free, Pro, and Team', + planTitle: process.env.FEATURE_REMOVE_FPT ? 'Dotcom TBD' : 'Free, Pro, and Team', releases: [latestNonNumberedRelease], latestRelease: latestNonNumberedRelease, nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes diff --git a/lib/find-page-in-version.js b/lib/find-page-in-version.js deleted file mode 100644 index d96f8259cd..0000000000 --- a/lib/find-page-in-version.js +++ /dev/null @@ -1,22 +0,0 @@ -const findPage = require('./find-page') -const getApplicableVersions = require('./get-applicable-versions') - -module.exports = function findPageInVersion (href, pageMap, redirects, languageCode, version, isDotcomOnly = false) { - // findPage() will throw an error if an English page can't be found - const page = findPage(href, pageMap, redirects, languageCode) - if (!page) return null - - // if the link is on the homepage, return the page as soon as it's found - if (version === 'homepage') return page - - // if the link is dotcom-only, return the page as soon as it's found - if (isDotcomOnly) return page - - // otherwise, get the versions that the found page is available in - const applicableVersions = getApplicableVersions(page.versions, page.fullPath) - - // return null if the found page's available versions do not include the specified version - if (!applicableVersions.includes(version)) return null - - return page -} diff --git a/lib/find-page.js b/lib/find-page.js deleted file mode 100644 index 03e2b10c9a..0000000000 --- a/lib/find-page.js +++ /dev/null @@ -1,69 +0,0 @@ -const slash = require('slash') -const patterns = require('./patterns') -const allVersions = Object.keys(require('./all-versions')) -const { getVersionedPathWithLanguage } = require('./path-utils') - -module.exports = function findPage (href, pageMap, redirects = {}, languageCode = 'en', sourceLanguage = null) { - // Convert Windows backslashes to forward slashes - // remove trailing slash - href = slash(href).replace(patterns.trailingSlash, '$1') - - // do an initial lookup on the path as-is - let page = pageMap[removeFragment(href)] - if (page) return page - - // check all potential versions - const versionedPathsToCheck = [...new Set(allVersions.map(version => { - return getVersionedPathWithLanguage(href, version, languageCode) - }))] - - // get the first found path of the page (account for redirects) - let pathToPage = versionedPathsToCheck.find(path => { - path = redirects[path] || path - return pageMap[removeFragment(path)] - }) - - // need to account for redirects again - pathToPage = redirects[pathToPage] || pathToPage - - // try finding the page again - page = pageMap[removeFragment(pathToPage)] - - if (page) return page - - if (process.env.NODE_ENV !== 'test' && languageCode === 'en') { - const error = sourceLanguage - ? `href not found in ${sourceLanguage} pages (no English fallback found)` - : 'href not found' - - // if English page can't be found, throw an error - // because these errors should be surfaced and fixed right away - if (sourceLanguage === 'en') { - throw new Error(`${error}: ${href}`) - } else { - console.error(`${error}: ${href}`) - } - } - - // if English page can't be found in tests, don't throw an error - // or the tests will stall - if (process.env.NODE_ENV === 'test' && languageCode === 'en') { - if (sourceLanguage === 'en') console.log(`href not found: ${href}`) - return null - } - - // if localized page can't be found, fall back to English - // because localized content is not yet synced - if (languageCode !== 'en') { - // pass the source language so we can surface it in error messages - return findPage(href, pageMap, redirects, 'en', languageCode) - } -} - -// some redirects include fragments -// need to remove the fragment to find the page -function removeFragment (path) { - if (!path) return - - return path.replace(/#.*$/, '') -} diff --git a/lib/liquid-tags/link.js b/lib/liquid-tags/link.js index b583b006ec..1d71eafdd2 100644 --- a/lib/liquid-tags/link.js +++ b/lib/liquid-tags/link.js @@ -2,9 +2,8 @@ const path = require('path') const assert = require('assert') const Liquid = require('liquid') const liquid = new Liquid.Engine() -const { getPathWithLanguage } = require('../path-utils') const LiquidTag = require('./liquid-tag') -const findPageInVersion = require('../find-page-in-version') +const getApplicableVersions = require('../get-applicable-versions') // This class supports a set of link tags. Each tag expects one parameter, a language-agnostic href: // @@ -52,17 +51,21 @@ module.exports = class Link extends LiquidTag { } // add language code - fullPath = getPathWithLanguage(fullPath, ctx.currentLanguage) + fullPath = path.join('/', ctx.currentLanguage, fullPath) // find the page based on the full path - const page = findPageInVersion(fullPath, ctx.pages, ctx.redirects, ctx.currentLanguage, ctx.currentVersion) + const page = ctx.pages[fullPath] || ctx.pages[ctx.redirects[fullPath]] - // if found page should NOT render in current version, return early with an empty string - // also return if it's a hidden link on a non-hidden page (hidden links on hidden pages are OK) + // return an empty string if it's a hidden link on a non-hidden page (hidden links on hidden pages are OK) if (!page || (page.hidden && !ctx.page.hidden)) { return '' } + // also return early if the found page should not render in current version + if (!getApplicableVersions(page.versions).includes(ctx.currentVersion)) { + return '' + } + // find and render the props const title = opts.shortTitle ? await page.renderProp('shortTitle', ctx, { textOnly: true, encodeEntities: true }) diff --git a/lib/path-utils.js b/lib/path-utils.js index d20a800ebc..6d75a185e3 100644 --- a/lib/path-utils.js +++ b/lib/path-utils.js @@ -1,77 +1,11 @@ const slash = require('slash') const path = require('path') const patterns = require('./patterns') -const { deprecated, latest } = require('./enterprise-server-releases') +const { latest } = require('./enterprise-server-releases') const allProducts = require('./all-products') const allVersions = require('./all-versions') const supportedVersions = new Set(Object.keys(allVersions)) -const { getNewVersionedPath } = require('./old-versions-utils') - -// This function constructs an appropriate versioned path for any given HREF. -// NOTE: this gets called by findPage and various other functions, and -// has to return a proper versioned link given a wide variety of incoming -// modern or legacy-formatted links, so it is somewhat overloaded. At some point -// this could probably be broken up into separate functions to handle different incoming -// paths. But it is currently optimized to handle lots of edge cases. -function getVersionedPathWithoutLanguage (href, version) { - // Start clean without language code or trailing slash - href = getPathWithoutLanguage(href.replace(patterns.trailingSlash, '$1')) - - // If this is an old versioned path that includes a deprecated version, do not change! - // example: /enterprise/11.10.340/admin/articles/upgrading-to-the-latest-release - const oldEnterpriseVersionNumber = href.match(patterns.getEnterpriseVersionNumber) - if (oldEnterpriseVersionNumber && deprecated.includes(oldEnterpriseVersionNumber[1])) { - return href - } - - // Try to derive the current version from the path - // example: enterprise-server@2.22 or free-pro-team@latest - let versionFromPath = getVersionStringFromPath(href) - - // If a supported version was found, add it to the path so we can go through the rest of the checks - if (supportedVersions.has(versionFromPath)) { - href = href.replace(href.split('/')[1], versionFromPath) - } - - // If a currently supported version was NOT found... - let productObjectFromPath - if (!supportedVersions.has(versionFromPath)) { - // First check if the segment is instead a current product; - // example: /admin/foo or /desktop/foo - productObjectFromPath = allProducts[versionFromPath] - - // If so, add the first supported version for that product to the href - // (this is just to get a path with all the expected segments; the version will be updated later if needed) - if (productObjectFromPath) { - href = path.join('/', productObjectFromPath.versions[0], href) - versionFromPath = productObjectFromPath.versions[0] - } else { - // Otherwise, this may be an old path that should be converted to new path; - // OLD: /enterprise/2.22/admin/installation OR /enterprise/admin/installation - // NEW: /enterprise-server@2.22/admin/installation - href = getNewVersionedPath(href) - versionFromPath = getVersionStringFromPath(href) - } - } - - // If not previously found, derive the product object from the path (e.g., github or admin) - if (!productObjectFromPath) { - productObjectFromPath = getProductObjectFromPath(href) - } - - // If the product's versions don't include the specified version, nothing to change! - if (productObjectFromPath && !productObjectFromPath.versions.includes(version)) { - return slash(href) - } - - // Update the version and return the path - return slash(href.replace(versionFromPath, version)) -} - -// Add language code to a versioned path -function getVersionedPathWithLanguage (href, version, languageCode) { - return getPathWithLanguage(getVersionedPathWithoutLanguage(href, version), languageCode) -} +const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') // Add the language to the given HREF // /articles/foo -> /en/articles/foo @@ -100,9 +34,15 @@ function getVersionStringFromPath (href) { return 'homepage' } - // Check if the first segment is a supported version + // Get the first segment const versionFromPath = href.split('/')[1] + // If the first segment is a supported product, assume this is FPT + if (allProducts[versionFromPath]) { + return nonEnterpriseDefaultVersion + } + + // Otherwise, check if it's a supported version if (supportedVersions.has(versionFromPath)) { return versionFromPath } @@ -133,9 +73,12 @@ function getVersionObjectFromPath (href) { // Return the product segment from the path function getProductStringFromPath (href) { href = getPathWithoutLanguage(href) - const productString = href.split('/')[2] - return productString || 'homepage' + if (href === '/') return 'homepage' + + return allProducts[href.split('/')[2]] + ? href.split('/')[2] + : href.split('/')[1] } // Return the corresponding object for the product segment in a path @@ -146,8 +89,6 @@ function getProductObjectFromPath (href) { } module.exports = { - getVersionedPathWithLanguage, - getVersionedPathWithoutLanguage, getPathWithLanguage, getPathWithoutLanguage, getPathWithoutVersion, diff --git a/lib/permalink.js b/lib/permalink.js index f432a993d1..dc5e42170d 100644 --- a/lib/permalink.js +++ b/lib/permalink.js @@ -1,9 +1,9 @@ const assert = require('assert') const path = require('path') const patterns = require('./patterns') -const pathUtils = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') const allVersions = require('./all-versions') +const removeFPTFromPath = require('./remove-fpt-from-path') class Permalink { constructor (languageCode, pageVersion, relativePath, title) { @@ -14,7 +14,7 @@ class Permalink { const permalinkSuffix = this.constructor.relativePathToSuffix(relativePath) - this.href = pathUtils.getVersionedPathWithLanguage(permalinkSuffix, pageVersion, languageCode) + this.href = removeFPTFromPath(path.join('/', languageCode, pageVersion, permalinkSuffix)) this.pageVersionTitle = allVersions[pageVersion].versionTitle diff --git a/lib/redirects/get-docs-path-from-developer-path.js b/lib/redirects/get-docs-path-from-developer-path.js index 5286bba04b..f919c2fa48 100644 --- a/lib/redirects/get-docs-path-from-developer-path.js +++ b/lib/redirects/get-docs-path-from-developer-path.js @@ -1,6 +1,6 @@ const patterns = require('../patterns') const { latest } = require('../enterprise-server-releases') -const { getVersionedPathWithLanguage } = require('../path-utils') +const { getPathWithoutLanguage } = require('../path-utils') // This function takes a known pre-migration path from developer.github.com and // infers and returns a current, correct docs.github.com path. @@ -73,7 +73,7 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed // old developer routes that include 'enterprise-admin' should always redirect to enterprise server if (fragment && newPath.includes('/rest/reference/enterprise-admin') && !patterns.enterpriseServer.test(newPath)) { - newPath = getVersionedPathWithLanguage(newPath, `enterprise-server@${latest}`, 'en') + newPath = `/en/enterprise-server@${latest}${getPathWithoutLanguage(newPath)}` } // show an error if the page to be redirected to doesn't exist diff --git a/lib/redirects/get-old-paths-from-permalink.js b/lib/redirects/get-old-paths-from-permalink.js index a636d02667..0718330ad1 100644 --- a/lib/redirects/get-old-paths-from-permalink.js +++ b/lib/redirects/get-old-paths-from-permalink.js @@ -57,13 +57,22 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren // ------ BEGIN MODERN VERSION FORMAT REPLACEMENTS ------// if (currentlySupportedVersions.includes(currentVersion) || versionSatisfiesRange(currentVersion, `>${lastReleaseWithLegacyFormat}`)) { (new Set(oldPaths)).forEach(oldPath => { - // create old path /github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace(`/${nonEnterpriseDefaultVersion}`, '')) + if (!process.env.FEATURE_REMOVE_FPT) { + // create old path /github from new path /free-pro-team@latest/github + oldPaths.add(oldPath + .replace(`/${nonEnterpriseDefaultVersion}`, '')) - // create old path /free-pro-team/github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace('@latest', '')) + // create old path /free-pro-team/github from new path /free-pro-team@latest/github + oldPaths.add(oldPath + .replace('@latest', '')) + } + + // TODO THIS ONE IS TRICKY BECAUSE OF VERSIONS TO ENABLE + // if (process.env.FEATURE_REMOVE_FPT) { + // // create old path /free-pro-team@latest/github from new path /github + // oldPaths.add(oldPath + // .replace(`/${nonEnterpriseDefaultVersion}`, '')) + // } // create old path /enterprise/ from new path /enterprise-server@ oldPaths.add(oldPath diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 57f3c4bfa9..21548b29d5 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -1,7 +1,10 @@ +const path = require('path') const patterns = require('../patterns') -const { getVersionedPathWithLanguage } = require('../path-utils') const supportedVersions = new Set(Object.keys(require('../all-versions'))) const getOldPathsFromPermalink = require('./get-old-paths-from-permalink') +const removeFPTFromPath = require('../remove-fpt-from-path') +const { getVersionStringFromPath } = require('../path-utils') +const { getNewVersionedPath } = require('../old-versions-utils') module.exports = function generateRedirectsForPermalinks (permalinks, redirectFrontmatter) { // account for Array or String frontmatter entries @@ -33,7 +36,9 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr } // get the old path for the current permalink version - const versionedFrontmatterOldPath = getVersionedPathWithLanguage(frontmatterOldPath, permalink.pageVersion, permalink.languageCode) + let versionedFrontmatterOldPath = path.join('/', permalink.languageCode, getNewVersionedPath(frontmatterOldPath)) + const versionFromPath = getVersionStringFromPath(versionedFrontmatterOldPath) + versionedFrontmatterOldPath = removeFPTFromPath(versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion)) // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href diff --git a/lib/redirects/precompile.js b/lib/redirects/precompile.js index d221a0f526..f61f124375 100755 --- a/lib/redirects/precompile.js +++ b/lib/redirects/precompile.js @@ -1,12 +1,9 @@ -const path = require('path') -const slash = require('slash') const patterns = require('../patterns') const { latest } = require('../enterprise-server-releases') const getOldPathsFromPermalink = require('../redirects/get-old-paths-from-permalink') const getDocsPathFromDevPath = require('../redirects/get-docs-path-from-developer-path') const DEVELOPER_ROUTES = require('../redirects/static/developer-docs-routes-for-supported-versions') const ARCHIVED_ROUTES = require('../redirects/static/archived-routes-from-213-to-217') -const nonEnterpriseDefaultVersion = require('../non-enterprise-default-version') // This function runs at server warmup and precompiles possible redirect routes. // It outputs them in key-value pairs within a neat Javascript object: { oldPath: newPath } @@ -59,27 +56,6 @@ module.exports = function precompileRedirects (pageList, pageMap) { allRedirects[developerRouteWithoutVersion] = newPathOnLatestVersion allRedirects[developerRouteWithLanguageWithoutVersion] = newPathOnLatestVersion } - - // given a developer route like `/enterprise/2.19/v3/activity`, - // add a veriation like `/enterprise/2.19/user/v3/activity`; - // we need to do this because all links in content get rewritten - // by lib/rewrite-local-links to include `/user` - if (developerRoute.includes('/enterprise/')) { - const developerRouteWithUserPath = developerRoute.replace(/\/(v[34])/, '/user/$1') - const developerRouteWithUserPathAndLanguage = `/en${developerRouteWithUserPath}` - allRedirects[developerRouteWithUserPath] = newPath - allRedirects[developerRouteWithUserPathAndLanguage] = newPath - } - - // given a developer route like `/v3/gists/comments`, - // add a veriation like `/free-pro-team@latest/v3/gists/comments`; - // again, we need to do this because all links in content get rewritten - if (!developerRoute.startsWith('/enterprise/')) { - const developerRouteWithVersion = slash(path.join(nonEnterpriseDefaultVersion, developerRoute)) - const developerRouteWithVersionAndLanguage = `/en/${developerRouteWithVersion}` - allRedirects[developerRouteWithVersion] = newPath - allRedirects[developerRouteWithVersionAndLanguage] = newPath - } }) return allRedirects diff --git a/lib/remove-fpt-from-path.js b/lib/remove-fpt-from-path.js new file mode 100644 index 0000000000..8d6cc49ccb --- /dev/null +++ b/lib/remove-fpt-from-path.js @@ -0,0 +1,11 @@ +const slash = require('slash') +const patterns = require('./patterns') +const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') + +module.exports = function removeFPTFromPath (path) { + path = process.env.FEATURE_REMOVE_FPT + ? slash(path.replace(`/${nonEnterpriseDefaultVersion}`, '')) + : path + + return path.replace(patterns.trailingSlash, '$1') +} diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index 889ca92e52..d91bcc0d35 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -1,7 +1,12 @@ -const externalRedirects = Object.keys(require('./redirects/external-sites')) -const pathUtils = require('./path-utils') const assert = require('assert') +const path = require('path') +const externalRedirects = Object.keys(require('./redirects/external-sites')) +const { getPathWithoutLanguage, getVersionStringFromPath } = require('./path-utils') +const { getNewVersionedPath } = require('./old-versions-utils') +const patterns = require('./patterns') +const { latest } = require('./enterprise-server-releases') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') +const removeFPTFromPath = require('./remove-fpt-from-path') const allVersions = require('./all-versions') const supportedVersions = Object.keys(allVersions) const supportedPlans = Object.values(allVersions).map(v => v.plan) @@ -28,7 +33,6 @@ function getNewHref (link, languageCode, version) { if (externalRedirects.includes(href)) return let newHref - // If the link has a hardcoded plan or version in it, do not update the version, just add the language code // Examples: // /enterprise-server@2.20/rest/reference/oauth-authorizations @@ -36,15 +40,40 @@ function getNewHref (link, languageCode, version) { // /enterprise-server@latest/rest/reference/oauth-authorizations (this redirects to the latest version) const firstLinkSegment = href.split('/')[1] if ([...supportedPlans, ...supportedVersions, 'enterprise-server@latest'].includes(firstLinkSegment)) { - newHref = pathUtils.getPathWithLanguage(href, languageCode) + newHref = path.join('/', languageCode, href) } // If link is dotcom-only, just get the language code // Otherwise, get the versioned path with language code if (!newHref) { - newHref = link.hasClass('dotcom-only') - ? pathUtils.getVersionedPathWithLanguage(href, nonEnterpriseDefaultVersion, languageCode) - : pathUtils.getVersionedPathWithLanguage(href, version, languageCode) + // start clean with no language (TOC pages already include the lang codes via lib/liquid-tags/link.js) + const hrefWithoutLang = getPathWithoutLanguage(href).replace(patterns.trailingSlash, '$1') + + // normalize any legacy links so they conform to new link structure + newHref = path.join('/', languageCode, getNewVersionedPath(hrefWithoutLang)) + + // get the current version from the link + const versionFromHref = getVersionStringFromPath(newHref) + + // ------ BEGIN ONE-OFF OVERRIDES ------// + // dotcom-only links always point to dotcom + if (link.hasClass('dotcom-only')) { + version = nonEnterpriseDefaultVersion + } + + // desktop links always point to dotcom + if (patterns.desktop.test(hrefWithoutLang)) { + version = nonEnterpriseDefaultVersion + } + + // admin links always point to Enterprise + if (patterns.adminProduct.test(hrefWithoutLang)) { + version = `enterprise-server@${latest}` + } + // ------ END ONE-OFF OVERRIDES ------// + + // update the version in the link + newHref = removeFPTFromPath(newHref.replace(versionFromHref, version)) } if (href !== newHref) link.attr('href', newHref) diff --git a/lib/site-tree.js b/lib/site-tree.js index 894085627e..0418bba526 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -1,10 +1,11 @@ const path = require('path') -const findPageInVersion = require('./find-page-in-version') -const products = Object.values(require('../lib/all-products')) -const { getVersionedPathWithLanguage, getPathWithLanguage } = require('./path-utils') +const products = Object.values(require('./all-products')) const languageCodes = Object.keys(require('./languages')) const addTitlesToTree = require('./site-tree-titles') const allVersions = Object.keys(require('./all-versions')) +const { getVersionStringFromPath } = require('./path-utils') +const getApplicableVersions = require('./get-applicable-versions') +const removeFPTFromPath = require('./remove-fpt-from-path') // This module builds a localized tree of every page on the site // It includes single-source pages that have different variants @@ -35,16 +36,20 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { return } - // we don't want versioned product links because these links already have a default version in them - product.href = getPathWithLanguage(item.href, languageCode) + product.href = path.join('/', languageCode, item.href) - // find the product TOC page and get TOC items - const page = findPageInVersion(item.href, pageMap, redirects, languageCode, version) + // find the product TOC page so we have access to the TOC items + const page = pageMap[item.href] || pageMap[redirects[item.href]] // skip if page can't be found in this version if (!page) return + if (!getApplicableVersions(page.versions).includes(version)) return - product.categories = buildCategoriesTree(page.tocItems, product.href, pageMap, redirects, version, languageCode) + // item.hrefs have a default version via lib/all-products, so update to the current version + const versionFromPath = getVersionStringFromPath(item.href) + const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, item.href.replace(versionFromPath, version))) + + product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version) productTree[item.id] = product return null @@ -59,24 +64,21 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { return siteTree } -function buildCategoriesTree (tocItems, productHref, pageMap, redirects, version, languageCode) { +function buildCategoriesTree (tocItems, versionedProductHref, pageMap, redirects, version) { const categoryTree = {} // for every category in a product TOC... tocItems.forEach(item => { const category = {} - const categoryHref = path.join(productHref, item.href) - - // we DO want versioned category links - const versionedCategoryHref = getVersionedPathWithLanguage(categoryHref, version, languageCode) - category.href = versionedCategoryHref + category.href = path.join(versionedProductHref, item.href) // find the category TOC page and get its TOC items - const page = findPageInVersion(versionedCategoryHref, pageMap, redirects, languageCode, version) + const page = pageMap[category.href] || pageMap[redirects[category.href]] // skip if page can't be found in this version if (!page) return + if (!getApplicableVersions(page.versions).includes(version)) return category.title = page.shortTitle || page.title @@ -92,19 +94,19 @@ function buildCategoriesTree (tocItems, productHref, pageMap, redirects, version // if TOC contains maptopics, build a maptopics tree // otherwise build an articles tree if (hasMaptopics) { - category.maptopics = buildMaptopicsTree(page.tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) + category.maptopics = buildMaptopicsTree(page.tocItems, category.href, pageMap, redirects, version) } else { - category.articles = buildArticlesTree(page.tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) + category.articles = buildArticlesTree(page.tocItems, category.href, pageMap, redirects, version) } } - categoryTree[versionedCategoryHref] = category + categoryTree[category.href] = category }) return categoryTree } -function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) { +function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects, version) { const maptopicTree = {} // for every maptopic in a category TOC... @@ -113,14 +115,14 @@ function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects .forEach(item => { const maptopic = {} - const versionedMaptopicHref = path.join(versionedCategoryHref, item.href) - maptopic.href = versionedMaptopicHref + maptopic.href = path.join(versionedCategoryHref, item.href) // find the category TOC page and get its TOC items - const page = findPageInVersion(versionedMaptopicHref, pageMap, redirects, languageCode, version) + const page = pageMap[maptopic.href] || pageMap[redirects[maptopic.href]] // skip if page can't be found in this version if (!page) return + if (!getApplicableVersions(page.versions).includes(version)) return // if this is not a maptopic, return early if (!page.mapTopic) return @@ -130,15 +132,15 @@ function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects maptopic.hidden = page.hidden // make the child articles accessible to the page object for maptopic rendering maptopic.childArticles = getChildArticles(tocItems, item.href) - maptopic.articles = buildArticlesTree(maptopic.childArticles, versionedCategoryHref, pageMap, redirects, version, languageCode) + maptopic.articles = buildArticlesTree(maptopic.childArticles, versionedCategoryHref, pageMap, redirects, version) - maptopicTree[versionedMaptopicHref] = maptopic + maptopicTree[maptopic.href] = maptopic }) return maptopicTree } -function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, version, languageCode) { +function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, version) { const articleTree = {} // REST categories may not have TOC items @@ -148,18 +150,18 @@ function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, tocItems.forEach(item => { const article = {} - const versionedArticleHref = path.join(versionedCategoryHref, item.href) - article.href = versionedArticleHref + article.href = path.join(versionedCategoryHref, item.href) // find the category TOC page and get its TOC items - const page = findPageInVersion(versionedArticleHref, pageMap, redirects, languageCode, version) + const page = pageMap[article.href] || pageMap[redirects[article.href]] // skip if page can't be found in this version if (!page) return + if (!getApplicableVersions(page.versions).includes(version)) return article.title = page.shortTitle || page.title - articleTree[versionedArticleHref] = article + articleTree[article.href] = article }) return articleTree diff --git a/middleware/archived-enterprise-versions.js b/middleware/archived-enterprise-versions.js index 1ede1b1504..c4b6d0fb39 100644 --- a/middleware/archived-enterprise-versions.js +++ b/middleware/archived-enterprise-versions.js @@ -5,7 +5,6 @@ const patterns = require('../lib/patterns') const versionSatisfiesRange = require('../lib/version-satisfies-range') const isArchivedVersion = require('../lib/is-archived-version') const got = require('got') -const findPage = require('../lib/find-page') // This module handles requests for deprecated GitHub Enterprise versions // by routing them to static content in help-docs-archived-enterprise-versions @@ -77,7 +76,7 @@ function getFallbackRedirects (req, requestedVersion) { const pathWithNewVersion = req.path.replace(requestedVersion, latest) // look for a page with the same path on a currently supported version - const currentlySupportedPage = findPage(pathWithNewVersion, req.context.pages, req.context.redirects) + const currentlySupportedPage = req.context.pages[pathWithNewVersion] || req.context.pages[req.context.redirects[pathWithNewVersion]] if (!currentlySupportedPage) return // get an array of viable old paths diff --git a/middleware/breadcrumbs.js b/middleware/breadcrumbs.js index 1087ab61f7..bc77e0cfc8 100644 --- a/middleware/breadcrumbs.js +++ b/middleware/breadcrumbs.js @@ -1,5 +1,6 @@ const path = require('path') const { getPathWithoutLanguage } = require('../lib/path-utils') +const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') module.exports = async (req, res, next) => { if (!req.context.page) return next() @@ -16,9 +17,6 @@ module.exports = async (req, res, next) => { // drop first '/' pathParts.shift() - // drop the version segment so pathParts now starts with /product - pathParts.shift() - const productPath = path.posix.join('/', req.context.currentProduct) const product = req.context.siteTree[req.language][req.context.currentVersion].products[req.context.currentProduct] @@ -31,6 +29,19 @@ module.exports = async (req, res, next) => { title: product.title } + // drop the version segment so pathParts now starts with /product + if (!process.env.FEATURE_REMOVE_FPT) { + pathParts.shift() + } + + if (process.env.FEATURE_REMOVE_FPT) { + // if this is not FPT, drop the version segment so pathParts now starts with /product + // if this is FPT, there is no version segment so pathParts already starts with /product + if (req.context.currentVersion !== nonEnterpriseDefaultVersion) { + pathParts.shift() + } + } + if (!pathParts[1]) return next() // get category path diff --git a/middleware/contextualizers/rest.js b/middleware/contextualizers/rest.js index 0d63f8d93f..198a4d312a 100644 --- a/middleware/contextualizers/rest.js +++ b/middleware/contextualizers/rest.js @@ -1,16 +1,18 @@ +const path = require('path') const rest = require('../../lib/rest') -const { getVersionedPathWithLanguage } = require('../../lib/path-utils') +const removeFPTFromPath = require('../../lib/remove-fpt-from-path') module.exports = async function (req, res, next) { req.context.rest = rest // link to include in `Works with GitHub Apps` notes // e.g. /ja/rest/reference/apps or /en/enterprise/2.20/user/rest/reference/apps - req.context.restGitHubAppsLink = getVersionedPathWithLanguage( - '/developers/apps', + req.context.restGitHubAppsLink = removeFPTFromPath(path.join( + '/', + req.context.currentLanguage, req.context.currentVersion, - req.context.currentLanguage - ) + '/developers/apps' + )) // ignore requests to non-REST reference paths if (!req.path.includes('rest/reference')) return next() diff --git a/middleware/featured-links.js b/middleware/featured-links.js index eeaba4fa34..7b3a55dec2 100644 --- a/middleware/featured-links.js +++ b/middleware/featured-links.js @@ -1,5 +1,5 @@ -const findPageInVersion = require('../lib/find-page-in-version') -const { getVersionedPathWithLanguage } = require('../lib/path-utils') +const path = require('path') +const removeFPTFromPath = require('../lib/remove-fpt-from-path') // this middleware adds properties to the context object module.exports = async (req, res, next) => { @@ -25,11 +25,10 @@ async function getLinkData (rawLinks, context) { const links = [] for (const link of rawLinks) { - const href = link.href - ? getVersionedPathWithLanguage(link.href, context.currentVersion, context.currentLanguage) - : getVersionedPathWithLanguage(link, context.currentVersion, context.currentLanguage) + const linkPath = link.href || link + const href = removeFPTFromPath(path.join('/', context.currentLanguage, context.currentVersion, linkPath)) - const linkedPage = findPageInVersion(href, context.pages, context.redirects, context.currentLanguage, context.currentVersion) + const linkedPage = context.pages[href] || context.pages[context.redirects[href]] if (!linkedPage) continue const opts = { textOnly: true, encodeEntities: true } diff --git a/tests/helpers/links-checker.js b/tests/helpers/links-checker.js index 97cfcb2de8..336c32aa63 100644 --- a/tests/helpers/links-checker.js +++ b/tests/helpers/links-checker.js @@ -3,10 +3,8 @@ const { union, uniq } = require('lodash') const fs = require('fs') const path = require('path') -const { getVersionStringFromPath } = require('../../lib/path-utils') const patterns = require('../../lib/patterns') const { deprecated } = require('../../lib/enterprise-server-releases') -const findPageInVersion = require('../../lib/find-page-in-version') const rest = require('../../middleware/contextualizers/rest') const graphql = require('../../middleware/contextualizers/graphql') const contextualize = require('../../middleware/context') @@ -145,11 +143,8 @@ class LinksChecker { if (gheVersionInLink && deprecated.includes(gheVersionInLink[1])) continue // ------ END ONEOFF EXCLUSIONS -------/// - // the link at this point should include a version via lib/rewrite-local-links - const versionFromHref = getVersionStringFromPath(link) - // look for linked page - const linkedPage = findPageInVersion(link, context.pages, context.redirects, this.languageCode, versionFromHref) + const linkedPage = context.pages[link] || context.pages[context.redirects[link]] this.checkedLinksCache.add(link) if (!linkedPage) { From 1faef35374df9b84698f2fc2fe74e965ab6f0fd7 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 7 Jan 2021 13:14:58 -0500 Subject: [PATCH 06/65] add feature flag for removing free-pro-team --- feature-flags.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/feature-flags.json b/feature-flags.json index 64c69f19d7..64d7876891 100644 --- a/feature-flags.json +++ b/feature-flags.json @@ -1,4 +1,5 @@ { "FEATURE_TEST_TRUE": true, - "FEATURE_TEST_FALSE": false + "FEATURE_TEST_FALSE": false, + "FEATURE_REMOVE_FPT": false } From 2356f6ae98a721dae040f45b91527e82d0f34735 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 7 Jan 2021 14:50:47 -0500 Subject: [PATCH 07/65] use GitHub.com for version name and add some comments --- lib/all-versions.js | 5 +++-- lib/remove-fpt-from-path.js | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/all-versions.js b/lib/all-versions.js index 083a1b26cc..d7fee98899 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -7,9 +7,10 @@ const versionDelimiter = '@' const latestNonNumberedRelease = 'latest' const plans = [ - { + { // free-pro-team is **not** a user-facing version and is stripped from URLs. + // See lib/remove-fpt-from-path.js for details. plan: 'free-pro-team', - planTitle: process.env.FEATURE_REMOVE_FPT ? 'Dotcom TBD' : 'Free, Pro, and Team', + planTitle: process.env.FEATURE_REMOVE_FPT ? 'GitHub.com' : 'Free, Pro, and Team', releases: [latestNonNumberedRelease], latestRelease: latestNonNumberedRelease, nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes diff --git a/lib/remove-fpt-from-path.js b/lib/remove-fpt-from-path.js index 8d6cc49ccb..e47251ac42 100644 --- a/lib/remove-fpt-from-path.js +++ b/lib/remove-fpt-from-path.js @@ -2,6 +2,9 @@ const slash = require('slash') const patterns = require('./patterns') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') +// This is a convenience function to remove free-pro-team@latest from all +// **user-facing** aspects of the site (particularly URLs) while continuing to support +// free-pro-team@latest as a version both in the codebase and in content/data files. module.exports = function removeFPTFromPath (path) { path = process.env.FEATURE_REMOVE_FPT ? slash(path.replace(`/${nonEnterpriseDefaultVersion}`, '')) From 1dd9f3cbf1b597c164992f1444ab5e3e262c0968 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 7 Jan 2021 15:21:22 -0500 Subject: [PATCH 08/65] account for homepage version --- middleware/featured-links.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/middleware/featured-links.js b/middleware/featured-links.js index 7b3a55dec2..7d36520d46 100644 --- a/middleware/featured-links.js +++ b/middleware/featured-links.js @@ -1,4 +1,5 @@ const path = require('path') +const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') const removeFPTFromPath = require('../lib/remove-fpt-from-path') // this middleware adds properties to the context object @@ -26,7 +27,8 @@ async function getLinkData (rawLinks, context) { for (const link of rawLinks) { const linkPath = link.href || link - const href = removeFPTFromPath(path.join('/', context.currentLanguage, context.currentVersion, linkPath)) + const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion + const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath)) const linkedPage = context.pages[href] || context.pages[context.redirects[href]] if (!linkedPage) continue From a6c48782c6e410252adc796c97baf2360a591e0d Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 7 Jan 2021 16:47:57 -0500 Subject: [PATCH 09/65] do not rewrite deprecated GHES links --- lib/rewrite-local-links.js | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index d91bcc0d35..2b94ac3e52 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -4,7 +4,7 @@ const externalRedirects = Object.keys(require('./redirects/external-sites')) const { getPathWithoutLanguage, getVersionStringFromPath } = require('./path-utils') const { getNewVersionedPath } = require('./old-versions-utils') const patterns = require('./patterns') -const { latest } = require('./enterprise-server-releases') +const { deprecated, latest } = require('./enterprise-server-releases') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') const removeFPTFromPath = require('./remove-fpt-from-path') const allVersions = require('./all-versions') @@ -24,16 +24,13 @@ module.exports = function rewriteLocalLinks ($, version, languageCode) { function getNewHref (link, languageCode, version) { const href = link.attr('href') - // these links should not be rewritten + // Exceptions to link rewriting if (href.startsWith('/assets')) return if (href.startsWith('/public')) return - - // Leave old redirected URLs intact - // e.g. `/contact` should not be replaced with `/en/contact` if (externalRedirects.includes(href)) return - let newHref - // If the link has a hardcoded plan or version in it, do not update the version, just add the language code + let newHref = href + // If the link has a hardcoded plan or version in it, do not update other than adding a language code // Examples: // /enterprise-server@2.20/rest/reference/oauth-authorizations // /enterprise-server/rest/reference/oauth-authorizations (this redirects to the latest version) @@ -43,11 +40,16 @@ function getNewHref (link, languageCode, version) { newHref = path.join('/', languageCode, href) } - // If link is dotcom-only, just get the language code - // Otherwise, get the versioned path with language code - if (!newHref) { + // If the link includes a deprecated version, do not update other than adding a language code + // Example: /enterprise/11.10.340/admin/articles/upgrading-to-the-latest-release + const oldEnterpriseVersionNumber = href.match(patterns.getEnterpriseVersionNumber) + if (oldEnterpriseVersionNumber && deprecated.includes(oldEnterpriseVersionNumber[1])) { + newHref = path.join('/', languageCode, href) + } + + if (newHref === href) { // start clean with no language (TOC pages already include the lang codes via lib/liquid-tags/link.js) - const hrefWithoutLang = getPathWithoutLanguage(href).replace(patterns.trailingSlash, '$1') + const hrefWithoutLang = getPathWithoutLanguage(href) // normalize any legacy links so they conform to new link structure newHref = path.join('/', languageCode, getNewVersionedPath(hrefWithoutLang)) @@ -76,5 +78,7 @@ function getNewHref (link, languageCode, version) { newHref = removeFPTFromPath(newHref.replace(versionFromHref, version)) } + newHref = newHref.replace(patterns.trailingSlash, '$1') + if (href !== newHref) link.attr('href', newHref) } From 5f42c407f3a98b8d9f7f6f286d70f2e4cf0f6d28 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 8 Jan 2021 11:05:55 -0500 Subject: [PATCH 10/65] add a few redirects to fake context object --- tests/unit/liquid-helpers.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index 7a66b64a48..f54f2b4566 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -13,7 +13,12 @@ describe('liquid helper tags', () => { context.currentLanguage = 'en' context.currentVersion = nonEnterpriseDefaultVersion context.pages = pageMap - context.redirects = [] + context.redirects = { + "/en/desktop/contributing-and-collaborating-using-github-desktop": `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, + "/ja/desktop/contributing-and-collaborating-using-github-desktop": `/ja/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, + "/en/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories": `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories`, + "/en/github/writing-on-github/basic-writing-and-formatting-syntax": `/en/${nonEnterpriseDefaultVersion}/github/writing-on-github/basic-writing-and-formatting-syntax` + } context.site = { data: { reusables: { From c3e34a77dbdd8ae0f28b370c4c7c487a5f50b56d Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 8 Jan 2021 11:16:21 -0500 Subject: [PATCH 11/65] only use enterprise-server for admin links on dotcom --- lib/rewrite-local-links.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index 2b94ac3e52..d04306b8f8 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -68,8 +68,8 @@ function getNewHref (link, languageCode, version) { version = nonEnterpriseDefaultVersion } - // admin links always point to Enterprise - if (patterns.adminProduct.test(hrefWithoutLang)) { + // admin links on dotcom always point to Enterprise + if (patterns.adminProduct.test(hrefWithoutLang) && version === nonEnterpriseDefaultVersion) { version = `enterprise-server@${latest}` } // ------ END ONE-OFF OVERRIDES ------// From d5eee9d01ea27b1f8556df2d4ed81ce8b597e5ca Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:48:54 -0500 Subject: [PATCH 12/65] add versioning to fix broken links --- .../about-repositories.md | 4 ++-- .../github/getting-started-with-github/keyboard-shortcuts.md | 2 +- content/github/managing-your-work-on-github/about-issues.md | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/content/github/creating-cloning-and-archiving-repositories/about-repositories.md b/content/github/creating-cloning-and-archiving-repositories/about-repositories.md index 2bf49ee038..214d30606e 100644 --- a/content/github/creating-cloning-and-archiving-repositories/about-repositories.md +++ b/content/github/creating-cloning-and-archiving-repositories/about-repositories.md @@ -22,8 +22,8 @@ Each person and organization can own unlimited repositories and invite an unlimi {% endif %} You can use repositories to manage your work and collaborate with others. -- You can use issues to collect user feedback, report software bugs, and organize tasks you'd like to accomplish. For more information, see "[About issues](/github/managing-your-work-on-github/about-issues)." -- {% data reusables.discussions.you-can-use-discussions %} +- You can use issues to collect user feedback, report software bugs, and organize tasks you'd like to accomplish. For more information, see "[About issues](/github/managing-your-work-on-github/about-issues)."{% if currentVersion == "free-pro-team@latest" %} +- {% data reusables.discussions.you-can-use-discussions %}{% endif %} - You can use pull requests to propose changes to a repository. For more information, see "[About pull requests](/github/collaborating-with-issues-and-pull-requests/about-pull-requests)." - You can use project boards to organize and prioritize your issues and pull requests. For more information, see "[About project boards](/github/managing-your-work-on-github/about-project-boards)." diff --git a/content/github/getting-started-with-github/keyboard-shortcuts.md b/content/github/getting-started-with-github/keyboard-shortcuts.md index f3f7cbdb3b..9f203f0aa9 100644 --- a/content/github/getting-started-with-github/keyboard-shortcuts.md +++ b/content/github/getting-started-with-github/keyboard-shortcuts.md @@ -33,7 +33,7 @@ Below is a list of some of the available keyboard shortcuts. |-----------|------------ |g c | Go to the **Code** tab |g i | Go to the **Issues** tab. For more information, see "[About issues](/articles/about-issues)." -|g p | Go to the **Pull requests** tab. For more information, see "[About pull requests](/articles/about-pull-requests)."{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" or currentVersion == "github-ae@latest" %} +|g p | Go to the **Pull requests** tab. For more information, see "[About pull requests](/articles/about-pull-requests)."{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} |g a | Go to the **Actions** tab. For more information, see "[About Actions](/actions/getting-started-with-github-actions/about-github-actions)."{% endif %} |g b | Go to the **Projects** tab. For more information, see "[About project boards](/articles/about-project-boards)." |g w | Go to the **Wiki** tab. For more information, see "[About wikis](/articles/about-wikis)." diff --git a/content/github/managing-your-work-on-github/about-issues.md b/content/github/managing-your-work-on-github/about-issues.md index 273387a467..9500408071 100644 --- a/content/github/managing-your-work-on-github/about-issues.md +++ b/content/github/managing-your-work-on-github/about-issues.md @@ -14,9 +14,11 @@ versions: You can collect user feedback, report software bugs, and organize tasks you'd like to accomplish with issues in a repository. Issues can act as more than just a place to report software bugs. +{% if currentVersion == "free-pro-team@latest" %} Other conversations are more suitable for discussions. {% data reusables.discussions.you-can-use-discussions %} {% data reusables.discussions.you-cannot-convert-a-discussion %} +{% endif %} {% data reusables.pull_requests.close-issues-using-keywords %} From f0244fa6456457d97083f847a8da58f3564288ab Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:49:21 -0500 Subject: [PATCH 13/65] reinstate a simplified findPage() --- lib/find-page.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 lib/find-page.js diff --git a/lib/find-page.js b/lib/find-page.js new file mode 100644 index 0000000000..3ee8737cc3 --- /dev/null +++ b/lib/find-page.js @@ -0,0 +1,17 @@ +const { getLanguageCode } = require('./patterns') + +module.exports = function findPage (href, pageMap, redirects) { + // remove any fragments + href = href.replace(/#.*$/, '') + + // find the page + const page = pageMap[href] || pageMap[redirects[href]] + if (page) return page + + // get the current language + const currentLang = getLanguageCode.test(href) ? href.match(getLanguageCode)[1] : 'en' + + // try to fall back to English if the translated page can't be found + const englishHref = href.replace(`/${currentLang}/`, '/en/') + return pageMap[englishHref] || pageMap[redirects[englishHref]] +} From d752732b16b74b8f1c3750b88e3458e361091850 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:49:35 -0500 Subject: [PATCH 14/65] update refs to reinstated findPage() --- lib/liquid-tags/link.js | 3 ++- lib/patterns.js | 1 + lib/redirects/get-docs-path-from-developer-path.js | 4 ++-- lib/redirects/precompile.js | 2 ++ lib/rewrite-local-links.js | 5 +++++ lib/site-tree.js | 9 +++++---- middleware/archived-enterprise-versions.js | 3 ++- middleware/contextualizers/graphql.js | 1 + middleware/featured-links.js | 3 ++- 9 files changed, 22 insertions(+), 9 deletions(-) diff --git a/lib/liquid-tags/link.js b/lib/liquid-tags/link.js index 1d71eafdd2..2d064c2c42 100644 --- a/lib/liquid-tags/link.js +++ b/lib/liquid-tags/link.js @@ -3,6 +3,7 @@ const assert = require('assert') const Liquid = require('liquid') const liquid = new Liquid.Engine() const LiquidTag = require('./liquid-tag') +const findPage = require('../find-page') const getApplicableVersions = require('../get-applicable-versions') // This class supports a set of link tags. Each tag expects one parameter, a language-agnostic href: @@ -54,7 +55,7 @@ module.exports = class Link extends LiquidTag { fullPath = path.join('/', ctx.currentLanguage, fullPath) // find the page based on the full path - const page = ctx.pages[fullPath] || ctx.pages[ctx.redirects[fullPath]] + const page = findPage(fullPath, ctx.pages, ctx.redirects) // return an empty string if it's a hidden link on a non-hidden page (hidden links on hidden pages are OK) if (!page || (page.hidden && !ctx.page.hidden)) { diff --git a/lib/patterns.js b/lib/patterns.js index 1184486b75..5075a64b29 100644 --- a/lib/patterns.js +++ b/lib/patterns.js @@ -39,6 +39,7 @@ module.exports = { oldEnterprisePath: /\/([a-z]{2}\/)?(enterprise\/)?(\S+?@(\S+?\/))?(\d.\d+\/)?(user[/$])?/, // new versioning format patterns adminProduct: /\/admin(\/|$|\?|#)/, + insightsProduct: /\/insights(\/|$|\?|#)/, enterpriseServer: /\/enterprise-server@/, getEnterpriseServerNumber: /enterprise-server@(\d+\.\d+)/ } diff --git a/lib/redirects/get-docs-path-from-developer-path.js b/lib/redirects/get-docs-path-from-developer-path.js index f919c2fa48..c50c6e3b81 100644 --- a/lib/redirects/get-docs-path-from-developer-path.js +++ b/lib/redirects/get-docs-path-from-developer-path.js @@ -1,6 +1,6 @@ const patterns = require('../patterns') const { latest } = require('../enterprise-server-releases') -const { getPathWithoutLanguage } = require('../path-utils') +const { getPathWithoutLanguage, getPathWithoutVersion } = require('../path-utils') // This function takes a known pre-migration path from developer.github.com and // infers and returns a current, correct docs.github.com path. @@ -73,7 +73,7 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed // old developer routes that include 'enterprise-admin' should always redirect to enterprise server if (fragment && newPath.includes('/rest/reference/enterprise-admin') && !patterns.enterpriseServer.test(newPath)) { - newPath = `/en/enterprise-server@${latest}${getPathWithoutLanguage(newPath)}` + newPath = `/en/enterprise-server@${latest}${getPathWithoutLanguage(getPathWithoutVersion(newPath))}` } // show an error if the page to be redirected to doesn't exist diff --git a/lib/redirects/precompile.js b/lib/redirects/precompile.js index f61f124375..99a1cd87e0 100755 --- a/lib/redirects/precompile.js +++ b/lib/redirects/precompile.js @@ -58,5 +58,7 @@ module.exports = function precompileRedirects (pageList, pageMap) { } }) + require('fs').writeFileSync('.redirect-cache', JSON.stringify(allRedirects, null, 2)) + return allRedirects } diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index d04306b8f8..59ffdee237 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -72,6 +72,11 @@ function getNewHref (link, languageCode, version) { if (patterns.adminProduct.test(hrefWithoutLang) && version === nonEnterpriseDefaultVersion) { version = `enterprise-server@${latest}` } + + // insights links on dotcom always point to Enterprise + if (patterns.insightsProduct.test(hrefWithoutLang) && version === nonEnterpriseDefaultVersion) { + version = `enterprise-server@${latest}` + } // ------ END ONE-OFF OVERRIDES ------// // update the version in the link diff --git a/lib/site-tree.js b/lib/site-tree.js index 97e0eaf407..da5b5cb60c 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -6,6 +6,7 @@ const allVersions = Object.keys(require('./all-versions')) const { getVersionStringFromPath } = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') const removeFPTFromPath = require('./remove-fpt-from-path') +const findPage = require('./find-page') // This module builds a localized tree of every page on the site // It includes single-source pages that have different variants @@ -39,7 +40,7 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { product.href = path.join('/', languageCode, item.href) // find the product TOC page so we have access to the TOC items - const page = pageMap[item.href] || pageMap[redirects[item.href]] + const page = findPage(item.href, pageMap, redirects) // skip if page can't be found in this version if (!page) return @@ -74,7 +75,7 @@ function buildCategoriesTree (tocItems, versionedProductHref, pageMap, redirects category.href = path.join(versionedProductHref, item.href) // find the category TOC page and get its TOC items - const page = pageMap[category.href] || pageMap[redirects[category.href]] + const page = findPage(category.href, pageMap, redirects) // skip if page can't be found in this version if (!page) return @@ -118,7 +119,7 @@ function buildMaptopicsTree (tocItems, versionedCategoryHref, pageMap, redirects maptopic.href = path.join(versionedCategoryHref, item.href) // find the category TOC page and get its TOC items - const page = pageMap[maptopic.href] || pageMap[redirects[maptopic.href]] + const page = findPage(maptopic.href, pageMap, redirects) // skip if page can't be found in this version if (!page) return @@ -153,7 +154,7 @@ function buildArticlesTree (tocItems, versionedCategoryHref, pageMap, redirects, article.href = path.join(versionedCategoryHref, item.href) // find the category TOC page and get its TOC items - const page = pageMap[article.href] || pageMap[redirects[article.href]] + const page = findPage(article.href, pageMap, redirects) // skip if page can't be found in this version if (!page) return diff --git a/middleware/archived-enterprise-versions.js b/middleware/archived-enterprise-versions.js index c4b6d0fb39..00cd5aaf23 100644 --- a/middleware/archived-enterprise-versions.js +++ b/middleware/archived-enterprise-versions.js @@ -4,6 +4,7 @@ const { latest, firstVersionDeprecatedOnNewSite, lastVersionWithoutStubbedRedire const patterns = require('../lib/patterns') const versionSatisfiesRange = require('../lib/version-satisfies-range') const isArchivedVersion = require('../lib/is-archived-version') +const findPage = require('../lib/find-page') const got = require('got') // This module handles requests for deprecated GitHub Enterprise versions @@ -76,7 +77,7 @@ function getFallbackRedirects (req, requestedVersion) { const pathWithNewVersion = req.path.replace(requestedVersion, latest) // look for a page with the same path on a currently supported version - const currentlySupportedPage = req.context.pages[pathWithNewVersion] || req.context.pages[req.context.redirects[pathWithNewVersion]] + const currentlySupportedPage = findPage(pathWithNewVersion, req.context.pages, req.context.redirects) if (!currentlySupportedPage) return // get an array of viable old paths diff --git a/middleware/contextualizers/graphql.js b/middleware/contextualizers/graphql.js index b5a1f7cc20..05214f1e9d 100644 --- a/middleware/contextualizers/graphql.js +++ b/middleware/contextualizers/graphql.js @@ -11,6 +11,7 @@ const explorerUrl = process.env.NODE_ENV === 'production' module.exports = async (req, res, next) => { // ignore requests to non-GraphQL reference paths if (!req.path.includes('/graphql/')) return next() + if (!allVersions[req.context.currentVersion]) return next() // Get the relevant name of the GraphQL schema files for the current version // For example, free-pro-team@latest corresponds to dotcom, diff --git a/middleware/featured-links.js b/middleware/featured-links.js index 7d36520d46..d7e665b5cd 100644 --- a/middleware/featured-links.js +++ b/middleware/featured-links.js @@ -1,6 +1,7 @@ const path = require('path') const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') const removeFPTFromPath = require('../lib/remove-fpt-from-path') +const findPage = require('../lib/find-page') // this middleware adds properties to the context object module.exports = async (req, res, next) => { @@ -30,7 +31,7 @@ async function getLinkData (rawLinks, context) { const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath)) - const linkedPage = context.pages[href] || context.pages[context.redirects[href]] + const linkedPage = findPage(href, context.pages, context.redirects) if (!linkedPage) continue const opts = { textOnly: true, encodeEntities: true } From 23170a50e67146a13488f67d12c5b12187089be3 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:50:05 -0500 Subject: [PATCH 15/65] lint --- tests/unit/liquid-helpers.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index f0f9d195a9..6ff424b07c 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -14,10 +14,10 @@ describe('liquid helper tags', () => { context.currentVersion = nonEnterpriseDefaultVersion context.pages = pageMap context.redirects = { - "/en/desktop/contributing-and-collaborating-using-github-desktop": `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, - "/ja/desktop/contributing-and-collaborating-using-github-desktop": `/ja/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, - "/en/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories": `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories`, - "/en/github/writing-on-github/basic-writing-and-formatting-syntax": `/en/${nonEnterpriseDefaultVersion}/github/writing-on-github/basic-writing-and-formatting-syntax` + '/en/desktop/contributing-and-collaborating-using-github-desktop': `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, + '/ja/desktop/contributing-and-collaborating-using-github-desktop': `/ja/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`, + '/en/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories': `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop/adding-and-cloning-repositories`, + '/en/github/writing-on-github/basic-writing-and-formatting-syntax': `/en/${nonEnterpriseDefaultVersion}/github/writing-on-github/basic-writing-and-formatting-syntax` } context.site = { data: { From e1cb587339b2cb1d2538cbf2dfa7d4d37e921764 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:50:20 -0500 Subject: [PATCH 16/65] update refs to reinstated findPage() --- tests/unit/find-page.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/unit/find-page.js b/tests/unit/find-page.js index 5772db5f01..e1f6748632 100644 --- a/tests/unit/find-page.js +++ b/tests/unit/find-page.js @@ -1,8 +1,6 @@ const path = require('path') const Page = require('../../lib/page') -const loadRedirects = require('../../lib/redirects/precompile') const findPage = require('../../lib/find-page') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') describe('find page', () => { jest.setTimeout(1000 * 1000) @@ -14,12 +12,15 @@ describe('find page', () => { languageCode: 'en' }) + const englishPermalink = page.permalinks[0].href + const japanesePermalink = englishPermalink.replace('/en/', '/ja/') + // add named keys const pageMap = { - [`/en/${nonEnterpriseDefaultVersion}/${page.relativePath}`]: page + [englishPermalink]: page } - const localizedPage = findPage(page.relativePath, pageMap, {}, 'ja') + const localizedPage = findPage(japanesePermalink, pageMap, {}) expect(typeof localizedPage.title).toBe('string') }) @@ -30,16 +31,15 @@ describe('find page', () => { languageCode: 'en' }) - const pageList = [page] + const englishPermalink = page.permalinks[0].href + const redirectToFind = '/some-old-path' // add named keys - const pageMap = {} - for (const page of pageList) { - pageMap[`/en/${nonEnterpriseDefaultVersion}/${page.relativePath.replace('.md', '')}`] = page + const pageMap = { + [englishPermalink]: page } - const redirects = await loadRedirects(pageList, pageMap) - const redirectedPage = findPage('some-old-path', pageMap, redirects, 'en') + const redirectedPage = findPage(redirectToFind, pageMap, page.buildRedirects()) expect(typeof redirectedPage.title).toBe('string') }) }) From e3d0009949eb9dd753725719d4ee4ca316601bf4 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Wed, 13 Jan 2021 16:50:54 -0500 Subject: [PATCH 17/65] remove no-longer needed tests for removed redirects now that legay /v3 and /v4 links have all been updated --- tests/fixtures/graphql-redirects.json | 50 --------------------------- 1 file changed, 50 deletions(-) diff --git a/tests/fixtures/graphql-redirects.json b/tests/fixtures/graphql-redirects.json index 9ebf98550b..60a618bd6c 100644 --- a/tests/fixtures/graphql-redirects.json +++ b/tests/fixtures/graphql-redirects.json @@ -42,27 +42,17 @@ "/en/enterprise/2.18/v4/union": "/en/enterprise/2.18/user/graphql/reference/unions", "/en/enterprise/2.18/v4/union/auditentryactor": "/en/enterprise/2.18/user/graphql/reference/unions#auditentryactor", "/en/enterprise/2.19/user/v4/enum": "/en/enterprise-server@2.19/graphql/reference/enums", - "/en/enterprise/2.19/user/v4/enum/auditlogorderfield": "/en/enterprise-server@2.19/graphql/reference/enums#auditlogorderfield", - "/en/enterprise/2.19/user/v4/enum/checkannotationlevel": "/en/enterprise-server@2.19/graphql/reference/enums#checkannotationlevel", "/en/enterprise/2.19/user/v4/guides": "/en/enterprise-server@2.19/graphql/guides", "/en/enterprise/2.19/user/v4/input_object": "/en/enterprise-server@2.19/graphql/reference/input-objects", "/en/enterprise/2.19/user/v4/interface": "/en/enterprise-server@2.19/graphql/reference/interfaces", - "/en/enterprise/2.19/user/v4/interface/actor": "/en/enterprise-server@2.19/graphql/reference/interfaces#actor", - "/en/enterprise/2.19/user/v4/interface/assignable": "/en/enterprise-server@2.19/graphql/reference/interfaces#assignable", "/en/enterprise/2.19/user/v4/mutation": "/en/enterprise-server@2.19/graphql/reference/mutations", "/en/enterprise/2.19/user/v4/object": "/en/enterprise-server@2.19/graphql/reference/objects", - "/en/enterprise/2.19/user/v4/object/actorlocation": "/en/enterprise-server@2.19/graphql/reference/objects#actorlocation", - "/en/enterprise/2.19/user/v4/object/addedtoprojectevent": "/en/enterprise-server@2.19/graphql/reference/objects#addedtoprojectevent", "/en/enterprise/2.19/user/v4/previews": "/en/enterprise-server@2.19/graphql/overview/schema-previews", "/en/enterprise/2.19/user/v4/public_schema": "/en/enterprise-server@2.19/graphql/overview/public-schema", "/en/enterprise/2.19/user/v4/query": "/en/enterprise-server@2.19/graphql/reference/queries", "/en/enterprise/2.19/user/v4/reference": "/en/enterprise-server@2.19/graphql/reference", "/en/enterprise/2.19/user/v4/scalar": "/en/enterprise-server@2.19/graphql/reference/scalars", - "/en/enterprise/2.19/user/v4/scalar/boolean": "/en/enterprise-server@2.19/graphql/reference/scalars#boolean", - "/en/enterprise/2.19/user/v4/scalar/date": "/en/enterprise-server@2.19/graphql/reference/scalars#date", "/en/enterprise/2.19/user/v4/union": "/en/enterprise-server@2.19/graphql/reference/unions", - "/en/enterprise/2.19/user/v4/union/assignee": "/en/enterprise-server@2.19/graphql/reference/unions#assignee", - "/en/enterprise/2.19/user/v4/union/auditentryactor": "/en/enterprise-server@2.19/graphql/reference/unions#auditentryactor", "/en/enterprise/2.19/v4/enum": "/en/enterprise-server@2.19/graphql/reference/enums", "/en/enterprise/2.19/v4/enum/auditlogorderfield": "/en/enterprise-server@2.19/graphql/reference/enums#auditlogorderfield", "/en/enterprise/2.19/v4/enum/checkannotationlevel": "/en/enterprise-server@2.19/graphql/reference/enums#checkannotationlevel", @@ -86,27 +76,17 @@ "/en/enterprise/2.19/v4/union/assignee": "/en/enterprise-server@2.19/graphql/reference/unions#assignee", "/en/enterprise/2.19/v4/union/auditentryactor": "/en/enterprise-server@2.19/graphql/reference/unions#auditentryactor", "/en/enterprise/2.20/user/v4/enum": "/en/enterprise-server@2.20/graphql/reference/enums", - "/en/enterprise/2.20/user/v4/enum/auditlogorderfield": "/en/enterprise-server@2.20/graphql/reference/enums#auditlogorderfield", - "/en/enterprise/2.20/user/v4/enum/checkannotationlevel": "/en/enterprise-server@2.20/graphql/reference/enums#checkannotationlevel", "/en/enterprise/2.20/user/v4/guides": "/en/enterprise-server@2.20/graphql/guides", "/en/enterprise/2.20/user/v4/input_object": "/en/enterprise-server@2.20/graphql/reference/input-objects", "/en/enterprise/2.20/user/v4/interface": "/en/enterprise-server@2.20/graphql/reference/interfaces", - "/en/enterprise/2.20/user/v4/interface/actor": "/en/enterprise-server@2.20/graphql/reference/interfaces#actor", - "/en/enterprise/2.20/user/v4/interface/assignable": "/en/enterprise-server@2.20/graphql/reference/interfaces#assignable", "/en/enterprise/2.20/user/v4/mutation": "/en/enterprise-server@2.20/graphql/reference/mutations", "/en/enterprise/2.20/user/v4/object": "/en/enterprise-server@2.20/graphql/reference/objects", - "/en/enterprise/2.20/user/v4/object/actorlocation": "/en/enterprise-server@2.20/graphql/reference/objects#actorlocation", - "/en/enterprise/2.20/user/v4/object/addedtoprojectevent": "/en/enterprise-server@2.20/graphql/reference/objects#addedtoprojectevent", "/en/enterprise/2.20/user/v4/previews": "/en/enterprise-server@2.20/graphql/overview/schema-previews", "/en/enterprise/2.20/user/v4/public_schema": "/en/enterprise-server@2.20/graphql/overview/public-schema", "/en/enterprise/2.20/user/v4/query": "/en/enterprise-server@2.20/graphql/reference/queries", "/en/enterprise/2.20/user/v4/reference": "/en/enterprise-server@2.20/graphql/reference", "/en/enterprise/2.20/user/v4/scalar": "/en/enterprise-server@2.20/graphql/reference/scalars", - "/en/enterprise/2.20/user/v4/scalar/boolean": "/en/enterprise-server@2.20/graphql/reference/scalars#boolean", - "/en/enterprise/2.20/user/v4/scalar/date": "/en/enterprise-server@2.20/graphql/reference/scalars#date", "/en/enterprise/2.20/user/v4/union": "/en/enterprise-server@2.20/graphql/reference/unions", - "/en/enterprise/2.20/user/v4/union/assignee": "/en/enterprise-server@2.20/graphql/reference/unions#assignee", - "/en/enterprise/2.20/user/v4/union/auditentryactor": "/en/enterprise-server@2.20/graphql/reference/unions#auditentryactor", "/en/enterprise/2.20/v4/enum": "/en/enterprise-server@2.20/graphql/reference/enums", "/en/enterprise/2.20/v4/enum/auditlogorderfield": "/en/enterprise-server@2.20/graphql/reference/enums#auditlogorderfield", "/en/enterprise/2.20/v4/enum/checkannotationlevel": "/en/enterprise-server@2.20/graphql/reference/enums#checkannotationlevel", @@ -130,27 +110,17 @@ "/en/enterprise/2.20/v4/union/assignee": "/en/enterprise-server@2.20/graphql/reference/unions#assignee", "/en/enterprise/2.20/v4/union/auditentryactor": "/en/enterprise-server@2.20/graphql/reference/unions#auditentryactor", "/en/enterprise/2.21/user/v4/enum": "/en/enterprise-server@2.21/graphql/reference/enums", - "/en/enterprise/2.21/user/v4/enum/auditlogorderfield": "/en/enterprise-server@2.21/graphql/reference/enums#auditlogorderfield", - "/en/enterprise/2.21/user/v4/enum/checkannotationlevel": "/en/enterprise-server@2.21/graphql/reference/enums#checkannotationlevel", "/en/enterprise/2.21/user/v4/guides": "/en/enterprise-server@2.21/graphql/guides", "/en/enterprise/2.21/user/v4/input_object": "/en/enterprise-server@2.21/graphql/reference/input-objects", "/en/enterprise/2.21/user/v4/interface": "/en/enterprise-server@2.21/graphql/reference/interfaces", - "/en/enterprise/2.21/user/v4/interface/actor": "/en/enterprise-server@2.21/graphql/reference/interfaces#actor", - "/en/enterprise/2.21/user/v4/interface/assignable": "/en/enterprise-server@2.21/graphql/reference/interfaces#assignable", "/en/enterprise/2.21/user/v4/mutation": "/en/enterprise-server@2.21/graphql/reference/mutations", "/en/enterprise/2.21/user/v4/object": "/en/enterprise-server@2.21/graphql/reference/objects", - "/en/enterprise/2.21/user/v4/object/actorlocation": "/en/enterprise-server@2.21/graphql/reference/objects#actorlocation", - "/en/enterprise/2.21/user/v4/object/addedtoprojectevent": "/en/enterprise-server@2.21/graphql/reference/objects#addedtoprojectevent", "/en/enterprise/2.21/user/v4/previews": "/en/enterprise-server@2.21/graphql/overview/schema-previews", "/en/enterprise/2.21/user/v4/public_schema": "/en/enterprise-server@2.21/graphql/overview/public-schema", "/en/enterprise/2.21/user/v4/query": "/en/enterprise-server@2.21/graphql/reference/queries", "/en/enterprise/2.21/user/v4/reference": "/en/enterprise-server@2.21/graphql/reference", "/en/enterprise/2.21/user/v4/scalar": "/en/enterprise-server@2.21/graphql/reference/scalars", - "/en/enterprise/2.21/user/v4/scalar/boolean": "/en/enterprise-server@2.21/graphql/reference/scalars#boolean", - "/en/enterprise/2.21/user/v4/scalar/date": "/en/enterprise-server@2.21/graphql/reference/scalars#date", "/en/enterprise/2.21/user/v4/union": "/en/enterprise-server@2.21/graphql/reference/unions", - "/en/enterprise/2.21/user/v4/union/assignee": "/en/enterprise-server@2.21/graphql/reference/unions#assignee", - "/en/enterprise/2.21/user/v4/union/auditentryactor": "/en/enterprise-server@2.21/graphql/reference/unions#auditentryactor", "/en/enterprise/2.21/v4/enum": "/en/enterprise-server@2.21/graphql/reference/enums", "/en/enterprise/2.21/v4/enum/auditlogorderfield": "/en/enterprise-server@2.21/graphql/reference/enums#auditlogorderfield", "/en/enterprise/2.21/v4/enum/checkannotationlevel": "/en/enterprise-server@2.21/graphql/reference/enums#checkannotationlevel", @@ -308,27 +278,17 @@ "/enterprise/2.19/v4/union/assignee": "/en/enterprise-server@2.19/graphql/reference/unions#assignee", "/enterprise/2.19/v4/union/auditentryactor": "/en/enterprise-server@2.19/graphql/reference/unions#auditentryactor", "/enterprise/2.20/user/v4/enum": "/en/enterprise-server@2.20/graphql/reference/enums", - "/enterprise/2.20/user/v4/enum/auditlogorderfield": "/en/enterprise-server@2.20/graphql/reference/enums#auditlogorderfield", - "/enterprise/2.20/user/v4/enum/checkannotationlevel": "/en/enterprise-server@2.20/graphql/reference/enums#checkannotationlevel", "/enterprise/2.20/user/v4/guides": "/en/enterprise-server@2.20/graphql/guides", "/enterprise/2.20/user/v4/input_object": "/en/enterprise-server@2.20/graphql/reference/input-objects", "/enterprise/2.20/user/v4/interface": "/en/enterprise-server@2.20/graphql/reference/interfaces", - "/enterprise/2.20/user/v4/interface/actor": "/en/enterprise-server@2.20/graphql/reference/interfaces#actor", - "/enterprise/2.20/user/v4/interface/assignable": "/en/enterprise-server@2.20/graphql/reference/interfaces#assignable", "/enterprise/2.20/user/v4/mutation": "/en/enterprise-server@2.20/graphql/reference/mutations", "/enterprise/2.20/user/v4/object": "/en/enterprise-server@2.20/graphql/reference/objects", - "/enterprise/2.20/user/v4/object/actorlocation": "/en/enterprise-server@2.20/graphql/reference/objects#actorlocation", - "/enterprise/2.20/user/v4/object/addedtoprojectevent": "/en/enterprise-server@2.20/graphql/reference/objects#addedtoprojectevent", "/enterprise/2.20/user/v4/previews": "/en/enterprise-server@2.20/graphql/overview/schema-previews", "/enterprise/2.20/user/v4/public_schema": "/en/enterprise-server@2.20/graphql/overview/public-schema", "/enterprise/2.20/user/v4/query": "/en/enterprise-server@2.20/graphql/reference/queries", "/enterprise/2.20/user/v4/reference": "/en/enterprise-server@2.20/graphql/reference", "/enterprise/2.20/user/v4/scalar": "/en/enterprise-server@2.20/graphql/reference/scalars", - "/enterprise/2.20/user/v4/scalar/boolean": "/en/enterprise-server@2.20/graphql/reference/scalars#boolean", - "/enterprise/2.20/user/v4/scalar/date": "/en/enterprise-server@2.20/graphql/reference/scalars#date", "/enterprise/2.20/user/v4/union": "/en/enterprise-server@2.20/graphql/reference/unions", - "/enterprise/2.20/user/v4/union/assignee": "/en/enterprise-server@2.20/graphql/reference/unions#assignee", - "/enterprise/2.20/user/v4/union/auditentryactor": "/en/enterprise-server@2.20/graphql/reference/unions#auditentryactor", "/enterprise/2.20/v4/enum": "/en/enterprise-server@2.20/graphql/reference/enums", "/enterprise/2.20/v4/enum/auditlogorderfield": "/en/enterprise-server@2.20/graphql/reference/enums#auditlogorderfield", "/enterprise/2.20/v4/enum/checkannotationlevel": "/en/enterprise-server@2.20/graphql/reference/enums#checkannotationlevel", @@ -352,27 +312,17 @@ "/enterprise/2.20/v4/union/assignee": "/en/enterprise-server@2.20/graphql/reference/unions#assignee", "/enterprise/2.20/v4/union/auditentryactor": "/en/enterprise-server@2.20/graphql/reference/unions#auditentryactor", "/enterprise/2.21/user/v4/enum": "/en/enterprise-server@2.21/graphql/reference/enums", - "/enterprise/2.21/user/v4/enum/auditlogorderfield": "/en/enterprise-server@2.21/graphql/reference/enums#auditlogorderfield", - "/enterprise/2.21/user/v4/enum/checkannotationlevel": "/en/enterprise-server@2.21/graphql/reference/enums#checkannotationlevel", "/enterprise/2.21/user/v4/guides": "/en/enterprise-server@2.21/graphql/guides", "/enterprise/2.21/user/v4/input_object": "/en/enterprise-server@2.21/graphql/reference/input-objects", "/enterprise/2.21/user/v4/interface": "/en/enterprise-server@2.21/graphql/reference/interfaces", - "/enterprise/2.21/user/v4/interface/actor": "/en/enterprise-server@2.21/graphql/reference/interfaces#actor", - "/enterprise/2.21/user/v4/interface/assignable": "/en/enterprise-server@2.21/graphql/reference/interfaces#assignable", "/enterprise/2.21/user/v4/mutation": "/en/enterprise-server@2.21/graphql/reference/mutations", "/enterprise/2.21/user/v4/object": "/en/enterprise-server@2.21/graphql/reference/objects", - "/enterprise/2.21/user/v4/object/actorlocation": "/en/enterprise-server@2.21/graphql/reference/objects#actorlocation", - "/enterprise/2.21/user/v4/object/addedtoprojectevent": "/en/enterprise-server@2.21/graphql/reference/objects#addedtoprojectevent", "/enterprise/2.21/user/v4/previews": "/en/enterprise-server@2.21/graphql/overview/schema-previews", "/enterprise/2.21/user/v4/public_schema": "/en/enterprise-server@2.21/graphql/overview/public-schema", "/enterprise/2.21/user/v4/query": "/en/enterprise-server@2.21/graphql/reference/queries", "/enterprise/2.21/user/v4/reference": "/en/enterprise-server@2.21/graphql/reference", "/enterprise/2.21/user/v4/scalar": "/en/enterprise-server@2.21/graphql/reference/scalars", - "/enterprise/2.21/user/v4/scalar/boolean": "/en/enterprise-server@2.21/graphql/reference/scalars#boolean", - "/enterprise/2.21/user/v4/scalar/date": "/en/enterprise-server@2.21/graphql/reference/scalars#date", "/enterprise/2.21/user/v4/union": "/en/enterprise-server@2.21/graphql/reference/unions", - "/enterprise/2.21/user/v4/union/assignee": "/en/enterprise-server@2.21/graphql/reference/unions#assignee", - "/enterprise/2.21/user/v4/union/auditentryactor": "/en/enterprise-server@2.21/graphql/reference/unions#auditentryactor", "/enterprise/2.21/v4/enum": "/en/enterprise-server@2.21/graphql/reference/enums", "/enterprise/2.21/v4/enum/auditlogorderfield": "/en/enterprise-server@2.21/graphql/reference/enums#auditlogorderfield", "/enterprise/2.21/v4/enum/checkannotationlevel": "/en/enterprise-server@2.21/graphql/reference/enums#checkannotationlevel", From b6032f285c3c5ea277cae1eb2711c7233fabfbc6 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 12:07:49 -0500 Subject: [PATCH 18/65] remove helper from this branch (to be re-added in child branch for easier reviewing) --- lib/all-products.js | 3 +-- lib/get-link-data.js | 3 +-- lib/permalink.js | 5 ++--- lib/redirects/permalinks.js | 3 +-- lib/remove-fpt-from-path.js | 14 -------------- lib/rewrite-local-links.js | 3 +-- lib/site-tree.js | 3 +-- middleware/contextualizers/rest.js | 5 ++--- 8 files changed, 9 insertions(+), 30 deletions(-) delete mode 100644 lib/remove-fpt-from-path.js diff --git a/lib/all-products.js b/lib/all-products.js index e56ffc21b3..e92bdf2d55 100644 --- a/lib/all-products.js +++ b/lib/all-products.js @@ -7,7 +7,6 @@ const yaml = require('js-yaml') const contentDir = path.join(process.cwd(), 'content') const frontmatter = require('@github-docs/frontmatter') const getApplicableVersions = require('./get-applicable-versions') -const removeFPTFromPath = require('./remove-fpt-from-path') // the product order is determined by data/products.yml const productsFile = path.join(process.cwd(), 'data/products.yml') @@ -47,7 +46,7 @@ sortedProductIds.forEach(productId => { const toc = slash(path.join(dir, 'index.md')) const { data } = frontmatter(fs.readFileSync(toc, 'utf8')) const applicableVersions = getApplicableVersions(data.versions, toc) - const href = removeFPTFromPath(`/${applicableVersions[0]}/${productId}`) + const href = `/${applicableVersions[0]}/${productId}` internalProducts[productId] = { id: productId, diff --git a/lib/get-link-data.js b/lib/get-link-data.js index 0d7a078d0a..6647ae85ce 100644 --- a/lib/get-link-data.js +++ b/lib/get-link-data.js @@ -1,7 +1,6 @@ const path = require('path') const findPage = require('./find-page') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') -const removeFPTFromPath = require('./remove-fpt-from-path') // rawLinks is an array of paths: [ '/foo' ] // we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ] @@ -13,7 +12,7 @@ module.exports = async (rawLinks, context, additionalProperties = []) => { for (const link of rawLinks) { const linkPath = link.href || link const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion - const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath)) + const href = path.join('/', context.currentLanguage, version, linkPath) const linkedPage = findPage(href, context.pages, context.redirects) if (!linkedPage) continue diff --git a/lib/permalink.js b/lib/permalink.js index dc5e42170d..6376c237cd 100644 --- a/lib/permalink.js +++ b/lib/permalink.js @@ -3,7 +3,6 @@ const path = require('path') const patterns = require('./patterns') const getApplicableVersions = require('./get-applicable-versions') const allVersions = require('./all-versions') -const removeFPTFromPath = require('./remove-fpt-from-path') class Permalink { constructor (languageCode, pageVersion, relativePath, title) { @@ -14,7 +13,8 @@ class Permalink { const permalinkSuffix = this.constructor.relativePathToSuffix(relativePath) - this.href = removeFPTFromPath(path.join('/', languageCode, pageVersion, permalinkSuffix)) + this.href = path.join('/', languageCode, pageVersion, permalinkSuffix) + .replace(patterns.trailingSlash, '$1') this.pageVersionTitle = allVersions[pageVersion].versionTitle @@ -49,7 +49,6 @@ class Permalink { return '/' + relativePath .replace('index.md', '') .replace('.md', '') - .replace(patterns.trailingSlash, '$1') } } diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 1a37273d90..82cdf9706e 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -2,7 +2,6 @@ const path = require('path') const patterns = require('../patterns') const supportedVersions = new Set(Object.keys(require('../all-versions'))) const getOldPathsFromPermalink = require('./get-old-paths-from-permalink') -const removeFPTFromPath = require('../remove-fpt-from-path') const { getVersionStringFromPath } = require('../path-utils') const { getNewVersionedPath } = require('../old-versions-utils') @@ -38,7 +37,7 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // get the old path for the current permalink version let versionedFrontmatterOldPath = path.join('/', permalink.languageCode, getNewVersionedPath(frontmatterOldPath)) const versionFromPath = getVersionStringFromPath(versionedFrontmatterOldPath) - versionedFrontmatterOldPath = removeFPTFromPath(versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion)) + versionedFrontmatterOldPath = versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion) // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href diff --git a/lib/remove-fpt-from-path.js b/lib/remove-fpt-from-path.js deleted file mode 100644 index e47251ac42..0000000000 --- a/lib/remove-fpt-from-path.js +++ /dev/null @@ -1,14 +0,0 @@ -const slash = require('slash') -const patterns = require('./patterns') -const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') - -// This is a convenience function to remove free-pro-team@latest from all -// **user-facing** aspects of the site (particularly URLs) while continuing to support -// free-pro-team@latest as a version both in the codebase and in content/data files. -module.exports = function removeFPTFromPath (path) { - path = process.env.FEATURE_REMOVE_FPT - ? slash(path.replace(`/${nonEnterpriseDefaultVersion}`, '')) - : path - - return path.replace(patterns.trailingSlash, '$1') -} diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index 59ffdee237..a13c08317e 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -6,7 +6,6 @@ const { getNewVersionedPath } = require('./old-versions-utils') const patterns = require('./patterns') const { deprecated, latest } = require('./enterprise-server-releases') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') -const removeFPTFromPath = require('./remove-fpt-from-path') const allVersions = require('./all-versions') const supportedVersions = Object.keys(allVersions) const supportedPlans = Object.values(allVersions).map(v => v.plan) @@ -80,7 +79,7 @@ function getNewHref (link, languageCode, version) { // ------ END ONE-OFF OVERRIDES ------// // update the version in the link - newHref = removeFPTFromPath(newHref.replace(versionFromHref, version)) + newHref = newHref.replace(versionFromHref, version) } newHref = newHref.replace(patterns.trailingSlash, '$1') diff --git a/lib/site-tree.js b/lib/site-tree.js index da5b5cb60c..66c64ab2e1 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -5,7 +5,6 @@ const addTitlesToTree = require('./site-tree-titles') const allVersions = Object.keys(require('./all-versions')) const { getVersionStringFromPath } = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') -const removeFPTFromPath = require('./remove-fpt-from-path') const findPage = require('./find-page') // This module builds a localized tree of every page on the site @@ -48,7 +47,7 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { // item.hrefs have a default version via lib/all-products, so update to the current version const versionFromPath = getVersionStringFromPath(item.href) - const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, item.href.replace(versionFromPath, version))) + const versionedProductHref = path.join('/', languageCode, item.href.replace(versionFromPath, version)) product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version) diff --git a/middleware/contextualizers/rest.js b/middleware/contextualizers/rest.js index 198a4d312a..81da836594 100644 --- a/middleware/contextualizers/rest.js +++ b/middleware/contextualizers/rest.js @@ -1,18 +1,17 @@ const path = require('path') const rest = require('../../lib/rest') -const removeFPTFromPath = require('../../lib/remove-fpt-from-path') module.exports = async function (req, res, next) { req.context.rest = rest // link to include in `Works with GitHub Apps` notes // e.g. /ja/rest/reference/apps or /en/enterprise/2.20/user/rest/reference/apps - req.context.restGitHubAppsLink = removeFPTFromPath(path.join( + req.context.restGitHubAppsLink = path.join( '/', req.context.currentLanguage, req.context.currentVersion, '/developers/apps' - )) + ) // ignore requests to non-REST reference paths if (!req.path.includes('rest/reference')) return next() From 39fe8cb96c221b104c652fbc1c796604c2add47f Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 12:08:01 -0500 Subject: [PATCH 19/65] add currentVersion to test context --- tests/unit/page.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/unit/page.js b/tests/unit/page.js index 6ead028b45..dfa472a04d 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -315,6 +315,7 @@ describe('Page class', () => { const context = { currentLanguage: 'en', currentProduct: 'snowbird', + currentVersion: nonEnterpriseDefaultVersion, site: { data: { 'learning-tracks': { From b5117580571fece2257df8dfc439a2c9f5c20fbb Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 13:34:32 -0500 Subject: [PATCH 20/65] add remove-fpt helper function --- lib/all-products.js | 3 ++- lib/all-versions.js | 2 +- lib/get-link-data.js | 3 ++- lib/permalink.js | 3 ++- lib/redirects/get-old-paths-from-permalink.js | 26 ++++++------------- lib/redirects/permalinks.js | 7 ++++- lib/redirects/precompile.js | 2 ++ lib/remove-fpt-from-path.js | 9 +++++++ lib/rewrite-local-links.js | 3 ++- lib/site-tree.js | 3 ++- middleware/breadcrumbs.js | 13 +++------- middleware/contextualizers/rest.js | 5 ++-- 12 files changed, 42 insertions(+), 37 deletions(-) create mode 100644 lib/remove-fpt-from-path.js diff --git a/lib/all-products.js b/lib/all-products.js index e92bdf2d55..e56ffc21b3 100644 --- a/lib/all-products.js +++ b/lib/all-products.js @@ -7,6 +7,7 @@ const yaml = require('js-yaml') const contentDir = path.join(process.cwd(), 'content') const frontmatter = require('@github-docs/frontmatter') const getApplicableVersions = require('./get-applicable-versions') +const removeFPTFromPath = require('./remove-fpt-from-path') // the product order is determined by data/products.yml const productsFile = path.join(process.cwd(), 'data/products.yml') @@ -46,7 +47,7 @@ sortedProductIds.forEach(productId => { const toc = slash(path.join(dir, 'index.md')) const { data } = frontmatter(fs.readFileSync(toc, 'utf8')) const applicableVersions = getApplicableVersions(data.versions, toc) - const href = `/${applicableVersions[0]}/${productId}` + const href = removeFPTFromPath(`/${applicableVersions[0]}/${productId}`) internalProducts[productId] = { id: productId, diff --git a/lib/all-versions.js b/lib/all-versions.js index d7fee98899..64fe6c9c8d 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -10,7 +10,7 @@ const plans = [ { // free-pro-team is **not** a user-facing version and is stripped from URLs. // See lib/remove-fpt-from-path.js for details. plan: 'free-pro-team', - planTitle: process.env.FEATURE_REMOVE_FPT ? 'GitHub.com' : 'Free, Pro, and Team', + planTitle: 'GitHub.com', releases: [latestNonNumberedRelease], latestRelease: latestNonNumberedRelease, nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes diff --git a/lib/get-link-data.js b/lib/get-link-data.js index 6647ae85ce..0d7a078d0a 100644 --- a/lib/get-link-data.js +++ b/lib/get-link-data.js @@ -1,6 +1,7 @@ const path = require('path') const findPage = require('./find-page') const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') +const removeFPTFromPath = require('./remove-fpt-from-path') // rawLinks is an array of paths: [ '/foo' ] // we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ] @@ -12,7 +13,7 @@ module.exports = async (rawLinks, context, additionalProperties = []) => { for (const link of rawLinks) { const linkPath = link.href || link const version = context.currentVersion === 'homepage' ? nonEnterpriseDefaultVersion : context.currentVersion - const href = path.join('/', context.currentLanguage, version, linkPath) + const href = removeFPTFromPath(path.join('/', context.currentLanguage, version, linkPath)) const linkedPage = findPage(href, context.pages, context.redirects) if (!linkedPage) continue diff --git a/lib/permalink.js b/lib/permalink.js index 6376c237cd..9a4950bda1 100644 --- a/lib/permalink.js +++ b/lib/permalink.js @@ -3,6 +3,7 @@ const path = require('path') const patterns = require('./patterns') const getApplicableVersions = require('./get-applicable-versions') const allVersions = require('./all-versions') +const removeFPTFromPath = require('./remove-fpt-from-path') class Permalink { constructor (languageCode, pageVersion, relativePath, title) { @@ -13,7 +14,7 @@ class Permalink { const permalinkSuffix = this.constructor.relativePathToSuffix(relativePath) - this.href = path.join('/', languageCode, pageVersion, permalinkSuffix) + this.href = removeFPTFromPath(path.join('/', languageCode, pageVersion, permalinkSuffix)) .replace(patterns.trailingSlash, '$1') this.pageVersionTitle = allVersions[pageVersion].versionTitle diff --git a/lib/redirects/get-old-paths-from-permalink.js b/lib/redirects/get-old-paths-from-permalink.js index a8781a72fb..8ee0e73db4 100644 --- a/lib/redirects/get-old-paths-from-permalink.js +++ b/lib/redirects/get-old-paths-from-permalink.js @@ -1,5 +1,5 @@ const { latest, lastReleaseWithLegacyFormat } = require('../enterprise-server-releases') -const { getPathWithoutLanguage, getPathWithLanguage } = require('../path-utils') +const { getPathWithoutLanguage, getPathWithLanguage, getVersionStringFromPath } = require('../path-utils') const patterns = require('../patterns') const versionSatisfiesRange = require('../version-satisfies-range') const currentlySupportedVersions = Object.keys(require('../all-versions')) @@ -11,6 +11,13 @@ const nonEnterpriseDefaultVersion = require('../non-enterprise-default-version') module.exports = function getOldPathsFromPath (currentPath, languageCode, currentVersion) { const oldPaths = new Set() + // This only applies to Dotcom paths, so no need to determine whether the version is deprecated + // create old path /free-pro-team@latest/github from new path /github + if (getVersionStringFromPath(currentPath) === nonEnterpriseDefaultVersion && !currentPath.includes(nonEnterpriseDefaultVersion)) { + oldPaths.add(currentPath + .replace(`/${languageCode}/`, `/${languageCode}/${nonEnterpriseDefaultVersion}/`)) + } + // ------ BEGIN LEGACY VERSION FORMAT REPLACEMENTS ------// // These remain relevant to handle legacy-formatted frontmatter redirects // and archived versions paths. @@ -57,23 +64,6 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren // ------ BEGIN MODERN VERSION FORMAT REPLACEMENTS ------// if (currentlySupportedVersions.includes(currentVersion) || versionSatisfiesRange(currentVersion, `>${lastReleaseWithLegacyFormat}`)) { (new Set(oldPaths)).forEach(oldPath => { - if (!process.env.FEATURE_REMOVE_FPT) { - // create old path /github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace(`/${nonEnterpriseDefaultVersion}`, '')) - - // create old path /free-pro-team/github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace('@latest', '')) - } - - // TODO THIS ONE IS TRICKY BECAUSE OF VERSIONS TO ENABLE - // if (process.env.FEATURE_REMOVE_FPT) { - // // create old path /free-pro-team@latest/github from new path /github - // oldPaths.add(oldPath - // .replace(`/${nonEnterpriseDefaultVersion}`, '')) - // } - // create old path /enterprise/ from new path /enterprise-server@ oldPaths.add(oldPath .replace(/\/enterprise-server@(\d)/, '/enterprise/$1')) diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 82cdf9706e..5b21948568 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -4,6 +4,7 @@ const supportedVersions = new Set(Object.keys(require('../all-versions'))) const getOldPathsFromPermalink = require('./get-old-paths-from-permalink') const { getVersionStringFromPath } = require('../path-utils') const { getNewVersionedPath } = require('../old-versions-utils') +const removeFPTFromPath = require('../remove-fpt-from-path') module.exports = function generateRedirectsForPermalinks (permalinks, redirectFrontmatter) { // account for Array or String frontmatter entries @@ -18,6 +19,10 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // get an array of possible old paths, e.g., /desktop/guides/ from current permalink /desktop/ const possibleOldPaths = getOldPathsFromPermalink(permalink.href, permalink.languageCode, permalink.pageVersion) + if (permalink.href === '/en/rest/reference/users') { + console.log(possibleOldPaths) + } + // for each old path, add a redirect to the current permalink possibleOldPaths.forEach(oldPath => { redirects[oldPath] = permalink.href @@ -37,7 +42,7 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // get the old path for the current permalink version let versionedFrontmatterOldPath = path.join('/', permalink.languageCode, getNewVersionedPath(frontmatterOldPath)) const versionFromPath = getVersionStringFromPath(versionedFrontmatterOldPath) - versionedFrontmatterOldPath = versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion) + versionedFrontmatterOldPath = removeFPTFromPath(versionedFrontmatterOldPath.replace(versionFromPath, permalink.pageVersion)) // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href diff --git a/lib/redirects/precompile.js b/lib/redirects/precompile.js index f61f124375..99a1cd87e0 100755 --- a/lib/redirects/precompile.js +++ b/lib/redirects/precompile.js @@ -58,5 +58,7 @@ module.exports = function precompileRedirects (pageList, pageMap) { } }) + require('fs').writeFileSync('.redirect-cache', JSON.stringify(allRedirects, null, 2)) + return allRedirects } diff --git a/lib/remove-fpt-from-path.js b/lib/remove-fpt-from-path.js new file mode 100644 index 0000000000..8bb72f802d --- /dev/null +++ b/lib/remove-fpt-from-path.js @@ -0,0 +1,9 @@ +const slash = require('slash') +const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') + +// This is a convenience function to remove free-pro-team@latest from all +// **user-facing** aspects of the site (particularly URLs) while continuing to support +// free-pro-team@latest as a version both in the codebase and in content/data files. +module.exports = function removeFPTFromPath (path) { + return slash(path.replace(`/${nonEnterpriseDefaultVersion}`, '')) +} diff --git a/lib/rewrite-local-links.js b/lib/rewrite-local-links.js index a13c08317e..76e30b6264 100644 --- a/lib/rewrite-local-links.js +++ b/lib/rewrite-local-links.js @@ -9,6 +9,7 @@ const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') const allVersions = require('./all-versions') const supportedVersions = Object.keys(allVersions) const supportedPlans = Object.values(allVersions).map(v => v.plan) +const removeFPTFromPath = require('./remove-fpt-from-path') // Content authors write links like `/some/article/path`, but they need to be // rewritten on the fly to match the current language and page version @@ -79,7 +80,7 @@ function getNewHref (link, languageCode, version) { // ------ END ONE-OFF OVERRIDES ------// // update the version in the link - newHref = newHref.replace(versionFromHref, version) + newHref = removeFPTFromPath(newHref.replace(versionFromHref, version)) } newHref = newHref.replace(patterns.trailingSlash, '$1') diff --git a/lib/site-tree.js b/lib/site-tree.js index 66c64ab2e1..d70cb13213 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -6,6 +6,7 @@ const allVersions = Object.keys(require('./all-versions')) const { getVersionStringFromPath } = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') const findPage = require('./find-page') +const removeFPTFromPath = require('./remove-fpt-from-path') // This module builds a localized tree of every page on the site // It includes single-source pages that have different variants @@ -47,7 +48,7 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { // item.hrefs have a default version via lib/all-products, so update to the current version const versionFromPath = getVersionStringFromPath(item.href) - const versionedProductHref = path.join('/', languageCode, item.href.replace(versionFromPath, version)) + const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, item.href.replace(versionFromPath, version))) product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version) diff --git a/middleware/breadcrumbs.js b/middleware/breadcrumbs.js index bc77e0cfc8..6d5b90cc8c 100644 --- a/middleware/breadcrumbs.js +++ b/middleware/breadcrumbs.js @@ -29,19 +29,12 @@ module.exports = async (req, res, next) => { title: product.title } - // drop the version segment so pathParts now starts with /product - if (!process.env.FEATURE_REMOVE_FPT) { + // if this is not FPT, drop the version segment so pathParts now starts with /product + // if this is FPT, there is no version segment so pathParts already starts with /product + if (req.context.currentVersion !== nonEnterpriseDefaultVersion) { pathParts.shift() } - if (process.env.FEATURE_REMOVE_FPT) { - // if this is not FPT, drop the version segment so pathParts now starts with /product - // if this is FPT, there is no version segment so pathParts already starts with /product - if (req.context.currentVersion !== nonEnterpriseDefaultVersion) { - pathParts.shift() - } - } - if (!pathParts[1]) return next() // get category path diff --git a/middleware/contextualizers/rest.js b/middleware/contextualizers/rest.js index 81da836594..198a4d312a 100644 --- a/middleware/contextualizers/rest.js +++ b/middleware/contextualizers/rest.js @@ -1,17 +1,18 @@ const path = require('path') const rest = require('../../lib/rest') +const removeFPTFromPath = require('../../lib/remove-fpt-from-path') module.exports = async function (req, res, next) { req.context.rest = rest // link to include in `Works with GitHub Apps` notes // e.g. /ja/rest/reference/apps or /en/enterprise/2.20/user/rest/reference/apps - req.context.restGitHubAppsLink = path.join( + req.context.restGitHubAppsLink = removeFPTFromPath(path.join( '/', req.context.currentLanguage, req.context.currentVersion, '/developers/apps' - ) + )) // ignore requests to non-REST reference paths if (!req.path.includes('rest/reference')) return next() From 850c2c6f2d84423c14396c4bd7d8b2d71b73144f Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 13:34:47 -0500 Subject: [PATCH 21/65] remove no longer needed feature flag --- feature-flags.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/feature-flags.json b/feature-flags.json index 64d7876891..64c69f19d7 100644 --- a/feature-flags.json +++ b/feature-flags.json @@ -1,5 +1,4 @@ { "FEATURE_TEST_TRUE": true, - "FEATURE_TEST_FALSE": false, - "FEATURE_REMOVE_FPT": false + "FEATURE_TEST_FALSE": false } From 64ada8a2929473e0821664f33c69716c997a608a Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 13:35:16 -0500 Subject: [PATCH 22/65] remove debugging code --- lib/redirects/precompile.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/redirects/precompile.js b/lib/redirects/precompile.js index 99a1cd87e0..f61f124375 100755 --- a/lib/redirects/precompile.js +++ b/lib/redirects/precompile.js @@ -58,7 +58,5 @@ module.exports = function precompileRedirects (pageList, pageMap) { } }) - require('fs').writeFileSync('.redirect-cache', JSON.stringify(allRedirects, null, 2)) - return allRedirects } From a78828a443aa19cdea78923158a203996a05ae06 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 13:51:18 -0500 Subject: [PATCH 23/65] remove debugging code --- lib/redirects/permalinks.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 5b21948568..b4fffb4cee 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -19,10 +19,6 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // get an array of possible old paths, e.g., /desktop/guides/ from current permalink /desktop/ const possibleOldPaths = getOldPathsFromPermalink(permalink.href, permalink.languageCode, permalink.pageVersion) - if (permalink.href === '/en/rest/reference/users') { - console.log(possibleOldPaths) - } - // for each old path, add a redirect to the current permalink possibleOldPaths.forEach(oldPath => { redirects[oldPath] = permalink.href From bf9982026ee53d846a65724095650de9d1708b3e Mon Sep 17 00:00:00 2001 From: skullface Date: Thu, 14 Jan 2021 14:02:35 -0500 Subject: [PATCH 24/65] use `https` over `http` --- includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/footer.html b/includes/footer.html index 7b46713fbd..bafadc053f 100644 --- a/includes/footer.html +++ b/includes/footer.html @@ -21,7 +21,7 @@

{% data ui.footer.platform.heading %}

From a4fc70d6d4fd577bff4e6bcfaadfce9b08d387bd Mon Sep 17 00:00:00 2001 From: skullface Date: Thu, 14 Jan 2021 15:04:52 -0500 Subject: [PATCH 26/65] use www --- includes/footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/footer.html b/includes/footer.html index e30c257c6e..d8c92ce3d0 100644 --- a/includes/footer.html +++ b/includes/footer.html @@ -33,7 +33,7 @@
  • {% data ui.footer.support.links.help %}
  • {% data ui.footer.support.links.community_forum %}
  • {% data ui.footer.support.links.training %}
  • -
  • {% data ui.footer.support.links.status %}
  • +
  • {% data ui.footer.support.links.status %}
  • {% data ui.footer.support.links.contact_github %}
  • From c61e5ce42a99603d6c48c86e3345004a5960cad5 Mon Sep 17 00:00:00 2001 From: skullface Date: Thu, 14 Jan 2021 15:08:00 -0500 Subject: [PATCH 27/65] use www --- includes/small-footer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/includes/small-footer.html b/includes/small-footer.html index 5e2e886c5c..61e56abbb4 100644 --- a/includes/small-footer.html +++ b/includes/small-footer.html @@ -8,7 +8,7 @@
  • {% data ui.footer.terms %}
  • {% data ui.footer.privacy %}
  • {% data ui.footer.product.links.security %}
  • -
  • {% data ui.footer.support.links.status %}
  • +
  • {% data ui.footer.support.links.status %}
  • {% data ui.footer.support.links.help %}
  • {% data ui.footer.support.links.contact_github %}
  • {% data ui.footer.product.links.pricing %}
  • From a66268cc836dc2e53349af9140f765414bddb3c7 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 17:07:09 -0500 Subject: [PATCH 28/65] add helper to middleware/breadcrumbs --- middleware/breadcrumbs.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/middleware/breadcrumbs.js b/middleware/breadcrumbs.js index 6d5b90cc8c..86970bde35 100644 --- a/middleware/breadcrumbs.js +++ b/middleware/breadcrumbs.js @@ -1,6 +1,7 @@ const path = require('path') const { getPathWithoutLanguage } = require('../lib/path-utils') const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') +const removeFPTFromPath = require('../lib/remove-fpt-from-path') module.exports = async (req, res, next) => { if (!req.context.page) return next() @@ -25,7 +26,7 @@ module.exports = async (req, res, next) => { } req.context.breadcrumbs.product = { - href: path.posix.join('/', req.context.currentLanguage, req.context.currentVersion, productPath), + href: removeFPTFromPath(path.posix.join('/', req.context.currentLanguage, req.context.currentVersion, productPath)), title: product.title } @@ -40,7 +41,7 @@ module.exports = async (req, res, next) => { // get category path // e.g., `getting-started-with-github` in /free-pro-team@latest/github/getting-started-with-github // or /enterprise-server@2.21/github/getting-started-with-github - const categoryPath = path.posix.join('/', req.context.currentLanguage, req.context.currentVersion, productPath, pathParts[1]) + const categoryPath = removeFPTFromPath(path.posix.join('/', req.context.currentLanguage, req.context.currentVersion, productPath, pathParts[1])) const category = product.categories[categoryPath] From 374112c55fcf689b50aa2b28486602ea06a9bf29 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 17:08:15 -0500 Subject: [PATCH 29/65] few tweaks to get passing tests --- lib/permalink.js | 10 +++++++--- lib/redirects/get-old-paths-from-permalink.js | 8 +++++--- lib/redirects/permalinks.js | 1 + lib/site-tree.js | 5 ++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib/permalink.js b/lib/permalink.js index 9a4950bda1..8ac4852080 100644 --- a/lib/permalink.js +++ b/lib/permalink.js @@ -3,6 +3,7 @@ const path = require('path') const patterns = require('./patterns') const getApplicableVersions = require('./get-applicable-versions') const allVersions = require('./all-versions') +const nonEnterpriseDefaultVersion = require('./non-enterprise-default-version') const removeFPTFromPath = require('./remove-fpt-from-path') class Permalink { @@ -27,9 +28,12 @@ class Permalink { assert(languageCode, 'languageCode is required') const applicableVersions = getApplicableVersions(frontmatterVersions, path.join(languageCode, relativePath)) - const permalinks = applicableVersions.map(pageVersion => { - return new Permalink(languageCode, pageVersion, relativePath, title) - }) + const permalinks = applicableVersions + // skip the Dotcom homepage here because a special homepage permalink is added below + .filter(pageVersion => !(pageVersion === nonEnterpriseDefaultVersion && relativePath === 'index.md')) + .map(pageVersion => { + return new Permalink(languageCode, pageVersion, relativePath, title) + }) // special permalink for homepage if (relativePath === 'index.md') { diff --git a/lib/redirects/get-old-paths-from-permalink.js b/lib/redirects/get-old-paths-from-permalink.js index 8ee0e73db4..df24db43b7 100644 --- a/lib/redirects/get-old-paths-from-permalink.js +++ b/lib/redirects/get-old-paths-from-permalink.js @@ -11,11 +11,13 @@ const nonEnterpriseDefaultVersion = require('../non-enterprise-default-version') module.exports = function getOldPathsFromPath (currentPath, languageCode, currentVersion) { const oldPaths = new Set() + const versionFromPath = getVersionStringFromPath(currentPath) + // This only applies to Dotcom paths, so no need to determine whether the version is deprecated - // create old path /free-pro-team@latest/github from new path /github - if (getVersionStringFromPath(currentPath) === nonEnterpriseDefaultVersion && !currentPath.includes(nonEnterpriseDefaultVersion)) { + // create old path /free-pro-team@latest/github from new path /github (or from a frontmatter `redirect_from` path like /articles) + if (versionFromPath === 'homepage' || !currentlySupportedVersions.includes(versionFromPath) || (versionFromPath === nonEnterpriseDefaultVersion && !currentPath.includes(nonEnterpriseDefaultVersion))) { oldPaths.add(currentPath - .replace(`/${languageCode}/`, `/${languageCode}/${nonEnterpriseDefaultVersion}/`)) + .replace(`/${languageCode}`, `/${languageCode}/${nonEnterpriseDefaultVersion}`)) } // ------ BEGIN LEGACY VERSION FORMAT REPLACEMENTS ------// diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index b4fffb4cee..33615ca77e 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -42,6 +42,7 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href + redirects[`/en${versionedFrontmatterOldPath}`] = permalink.href // then get an array of possible alternative old paths from the current versioned old path const possibleOldPathsForVersionedOldPaths = getOldPathsFromPermalink(versionedFrontmatterOldPath, permalink.languageCode, permalink.pageVersion) diff --git a/lib/site-tree.js b/lib/site-tree.js index d70cb13213..99eb62ff6b 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -3,7 +3,7 @@ const products = Object.values(require('./all-products')) const languageCodes = Object.keys(require('./languages')) const addTitlesToTree = require('./site-tree-titles') const allVersions = Object.keys(require('./all-versions')) -const { getVersionStringFromPath } = require('./path-utils') +const { getPathWithoutVersion } = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') const findPage = require('./find-page') const removeFPTFromPath = require('./remove-fpt-from-path') @@ -47,8 +47,7 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { if (!getApplicableVersions(page.versions).includes(version)) return // item.hrefs have a default version via lib/all-products, so update to the current version - const versionFromPath = getVersionStringFromPath(item.href) - const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, item.href.replace(versionFromPath, version))) + const versionedProductHref = removeFPTFromPath(path.join('/', languageCode, version, getPathWithoutVersion(item.href))) product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version) From affbc80a3c3b03efda5a25533cd4f137f9647592 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 17:08:30 -0500 Subject: [PATCH 30/65] update tests to remove free-pro-team from expected results --- tests/content/featured-links.js | 6 +- tests/content/site-tree.js | 10 +- tests/fixtures/developer-redirects.json | 44 ++--- tests/fixtures/graphql-redirects.json | 104 +++++------ tests/fixtures/rest-redirects.json | 210 +++++++++++----------- tests/rendering/breadcrumbs.js | 30 ++-- tests/rendering/header.js | 10 +- tests/rendering/server.js | 28 +-- tests/rendering/sidebar.js | 2 +- tests/routing/developer-site-redirects.js | 19 +- tests/routing/redirects.js | 16 +- tests/unit/liquid-helpers.js | 4 +- tests/unit/page.js | 21 ++- tests/unit/permalink.js | 8 +- tests/unit/versions.js | 2 +- 15 files changed, 258 insertions(+), 256 deletions(-) diff --git a/tests/content/featured-links.js b/tests/content/featured-links.js index 9829f1abd7..45d41b9190 100644 --- a/tests/content/featured-links.js +++ b/tests/content/featured-links.js @@ -16,11 +16,11 @@ describe('featuredLinks', () => { const $ = await getDOM('/en') const $featuredLinks = $('.featured-links a') expect($featuredLinks).toHaveLength(9) - expect($featuredLinks.eq(0).attr('href')).toBe(`/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github/set-up-git`) + expect($featuredLinks.eq(0).attr('href')).toBe(`/en/github/getting-started-with-github/set-up-git`) expect($featuredLinks.eq(0).children('h4').text().startsWith('Set up Git')).toBe(true) expect($featuredLinks.eq(0).children('p').text().startsWith('At the heart of GitHub')).toBe(true) - expect($featuredLinks.eq(8).attr('href')).toBe(`/en/${nonEnterpriseDefaultVersion}/github/working-with-github-pages`) + expect($featuredLinks.eq(8).attr('href')).toBe(`/en/github/working-with-github-pages`) expect($featuredLinks.eq(8).children('h4').text().startsWith('GitHub Pages')).toBe(true) expect($featuredLinks.eq(8).children('p').text().startsWith('You can create a website')).toBe(true) }) @@ -58,7 +58,7 @@ describe('featuredLinks', () => { test('returns modified array of links', async () => { const gettingStartedLinks = await getJSON('/en?json=featuredLinks.gettingStarted') const expectedFirstLink = { - href: `/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github/set-up-git`, + href: `/en/github/getting-started-with-github/set-up-git`, title: 'Set up Git' } expect(gettingStartedLinks[0].href).toEqual(expectedFirstLink.href) diff --git a/tests/content/site-tree.js b/tests/content/site-tree.js index 1f1d49ef33..74ccdf6d70 100644 --- a/tests/content/site-tree.js +++ b/tests/content/site-tree.js @@ -24,23 +24,23 @@ describe('siteTree', () => { test('object order', () => { expect(Object.keys(siteTree)[0]).toBe('en') expect(Object.keys(siteTree.en)[0]).toBe(nonEnterpriseDefaultVersion) - expect(Object.keys(siteTree.en[nonEnterpriseDefaultVersion].products.github.categories)[0]).toBe(`/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github`) + expect(Object.keys(siteTree.en[nonEnterpriseDefaultVersion].products.github.categories)[0]).toBe(`/en/github/getting-started-with-github`) }) test('object structure', () => { expect(nonEnterpriseDefaultVersion in siteTree.en).toBe(true) expect(`enterprise-server@${latestEnterpriseRelease}` in siteTree.en).toBe(true) - expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.href`]).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) - expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github.href`]).toBe(`/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github`) + expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.href`]).toBe(`/en/github`) + expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/github/getting-started-with-github.href`]).toBe(`/en/github/getting-started-with-github`) }) describe('localized titles', () => { test('titles for categories', () => { - const japaneseTitle = flatTree[`ja.${nonEnterpriseDefaultVersion}.products.github.categories./ja/${nonEnterpriseDefaultVersion}/github/getting-started-with-github.title`] + const japaneseTitle = flatTree[`ja.${nonEnterpriseDefaultVersion}.products.github.categories./ja/github/getting-started-with-github.title`] expect(typeof japaneseTitle).toBe('string') expect(japaneseCharacters.presentIn(japaneseTitle)).toBe(true) - const englishTitle = flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github.title`] + const englishTitle = flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/github/getting-started-with-github.title`] expect(typeof englishTitle).toBe('string') expect(japaneseCharacters.presentIn(englishTitle)).toBe(false) }) diff --git a/tests/fixtures/developer-redirects.json b/tests/fixtures/developer-redirects.json index 16ad801b12..21942051ec 100644 --- a/tests/fixtures/developer-redirects.json +++ b/tests/fixtures/developer-redirects.json @@ -1,26 +1,26 @@ { - "/apps": "/en/free-pro-team@latest/developers/apps", - "/apps/building-github-apps": "/en/free-pro-team@latest/developers/apps/building-github-apps", - "/apps/building-oauth-apps": "/en/free-pro-team@latest/developers/apps/building-oauth-apps", - "/apps/managing-github-apps": "/en/free-pro-team@latest/developers/apps/managing-github-apps", - "/apps/managing-oauth-apps": "/en/free-pro-team@latest/developers/apps/managing-oauth-apps", - "/apps/quickstart-guides": "/en/free-pro-team@latest/developers/apps/guides", - "/marketplace": "/en/free-pro-team@latest/developers/github-marketplace", - "/marketplace/getting-started": "/en/free-pro-team@latest/developers/github-marketplace/about-github-marketplace", - "/marketplace/integrating-with-the-github-marketplace-api": "/en/free-pro-team@latest/developers/github-marketplace/using-the-github-marketplace-api-in-your-app", - "/marketplace/listing-on-github-marketplace": "/en/free-pro-team@latest/developers/github-marketplace/listing-an-app-on-github-marketplace", - "/marketplace/selling-your-app": "/en/free-pro-team@latest/developers/github-marketplace/selling-your-app-on-github-marketplace", - "/v3": "/en/free-pro-team@latest/rest", - "/v3/actions/workflow-jobs": "/en/free-pro-team@latest/rest/reference/actions#workflow-jobs", - "/v3/actions/workflow-runs": "/en/free-pro-team@latest/rest/reference/actions#workflow-runs", - "/v3/actions/workflow_jobs": "/en/free-pro-team@latest/rest/reference/actions#workflow-jobs", - "/v3/actions/workflow_runs": "/en/free-pro-team@latest/rest/reference/actions#workflow-runs", - "/v3/guides": "/en/free-pro-team@latest/rest/guides", - "/v3/guides/managing-deploy-keys": "/en/free-pro-team@latest/developers/overview/managing-deploy-keys", - "/v3/misc": "/en/free-pro-team@latest/rest/reference/emojis", - "/v4/public_schema": "/en/free-pro-team@latest/graphql/overview/public-schema", - "/v4/object/repository": "/en/free-pro-team@latest/graphql/reference/objects#repository", - "/webhooks": "/en/free-pro-team@latest/developers/webhooks-and-events/about-webhooks", + "/apps": "/en/developers/apps", + "/apps/building-github-apps": "/en/developers/apps/building-github-apps", + "/apps/building-oauth-apps": "/en/developers/apps/building-oauth-apps", + "/apps/managing-github-apps": "/en/developers/apps/managing-github-apps", + "/apps/managing-oauth-apps": "/en/developers/apps/managing-oauth-apps", + "/apps/quickstart-guides": "/en/developers/apps/guides", + "/marketplace": "/en/developers/github-marketplace", + "/marketplace/getting-started": "/en/developers/github-marketplace/about-github-marketplace", + "/marketplace/integrating-with-the-github-marketplace-api": "/en/developers/github-marketplace/using-the-github-marketplace-api-in-your-app", + "/marketplace/listing-on-github-marketplace": "/en/developers/github-marketplace/listing-an-app-on-github-marketplace", + "/marketplace/selling-your-app": "/en/developers/github-marketplace/selling-your-app-on-github-marketplace", + "/v3": "/en/rest", + "/v3/actions/workflow-jobs": "/en/rest/reference/actions#workflow-jobs", + "/v3/actions/workflow-runs": "/en/rest/reference/actions#workflow-runs", + "/v3/actions/workflow_jobs": "/en/rest/reference/actions#workflow-jobs", + "/v3/actions/workflow_runs": "/en/rest/reference/actions#workflow-runs", + "/v3/guides": "/en/rest/guides", + "/v3/guides/managing-deploy-keys": "/en/developers/overview/managing-deploy-keys", + "/v3/misc": "/en/rest/reference/emojis", + "/v4/public_schema": "/en/graphql/overview/public-schema", + "/v4/object/repository": "/en/graphql/reference/objects#repository", + "/webhooks": "/en/developers/webhooks-and-events/about-webhooks", "/en/enterprise/2.18/apps": "/en/enterprise/2.18/user/developers/apps", "/en/enterprise/2.18/apps/building-oauth-apps/authorizing-oauth-apps": "/en/enterprise/2.18/user/developers/apps/authorizing-oauth-apps", "/en/enterprise/2.18/apps/building-oauth-apps/understanding-scopes-for-oauth-apps": "/en/enterprise/2.18/user/developers/apps/scopes-for-oauth-apps", diff --git a/tests/fixtures/graphql-redirects.json b/tests/fixtures/graphql-redirects.json index 60a618bd6c..5e6dd2df7a 100644 --- a/tests/fixtures/graphql-redirects.json +++ b/tests/fixtures/graphql-redirects.json @@ -165,32 +165,32 @@ "/en/enterprise/v4/union": "/en/enterprise-server/graphql/reference/unions", "/en/enterprise/v4/union/assignee": "/en/enterprise-server/graphql/reference/unions#assignee", "/en/enterprise/v4/union/auditentryactor": "/en/enterprise-server/graphql/reference/unions#auditentryactor", - "/en/v4/enum": "/en/free-pro-team@latest/graphql/reference/enums", - "/en/v4/enum/auditlogorderfield": "/en/free-pro-team@latest/graphql/reference/enums#auditlogorderfield", - "/en/v4/enum/checkannotationlevel": "/en/free-pro-team@latest/graphql/reference/enums#checkannotationlevel", - "/en/v4/guides": "/en/free-pro-team@latest/graphql/guides", - "/en/v4/input_object": "/en/free-pro-team@latest/graphql/reference/input-objects", - "/en/v4/input_object/acceptenterpriseadministratorinvitationinput": "/en/free-pro-team@latest/graphql/reference/input-objects#acceptenterpriseadministratorinvitationinput", - "/en/v4/input_object/accepttopicsuggestioninput": "/en/free-pro-team@latest/graphql/reference/input-objects#accepttopicsuggestioninput", - "/en/v4/interface": "/en/free-pro-team@latest/graphql/reference/interfaces", - "/en/v4/interface/actor": "/en/free-pro-team@latest/graphql/reference/interfaces#actor", - "/en/v4/interface/assignable": "/en/free-pro-team@latest/graphql/reference/interfaces#assignable", - "/en/v4/mutation": "/en/free-pro-team@latest/graphql/reference/mutations", - "/en/v4/mutation/acceptenterpriseadministratorinvitation": "/en/free-pro-team@latest/graphql/reference/mutations#acceptenterpriseadministratorinvitation", - "/en/v4/mutation/accepttopicsuggestion": "/en/free-pro-team@latest/graphql/reference/mutations#accepttopicsuggestion", - "/en/v4/object": "/en/free-pro-team@latest/graphql/reference/objects", - "/en/v4/object/actorlocation": "/en/free-pro-team@latest/graphql/reference/objects#actorlocation", - "/en/v4/object/addedtoprojectevent": "/en/free-pro-team@latest/graphql/reference/objects#addedtoprojectevent", - "/en/v4/previews": "/en/free-pro-team@latest/graphql/overview/schema-previews", - "/en/v4/public_schema": "/en/free-pro-team@latest/graphql/overview/public-schema", - "/en/v4/query": "/en/free-pro-team@latest/graphql/reference/queries", - "/en/v4/reference": "/en/free-pro-team@latest/graphql/reference", - "/en/v4/scalar": "/en/free-pro-team@latest/graphql/reference/scalars", - "/en/v4/scalar/boolean": "/en/free-pro-team@latest/graphql/reference/scalars#boolean", - "/en/v4/scalar/date": "/en/free-pro-team@latest/graphql/reference/scalars#date", - "/en/v4/union": "/en/free-pro-team@latest/graphql/reference/unions", - "/en/v4/union/assignee": "/en/free-pro-team@latest/graphql/reference/unions#assignee", - "/en/v4/union/auditentryactor": "/en/free-pro-team@latest/graphql/reference/unions#auditentryactor", + "/en/v4/enum": "/en/graphql/reference/enums", + "/en/v4/enum/auditlogorderfield": "/en/graphql/reference/enums#auditlogorderfield", + "/en/v4/enum/checkannotationlevel": "/en/graphql/reference/enums#checkannotationlevel", + "/en/v4/guides": "/en/graphql/guides", + "/en/v4/input_object": "/en/graphql/reference/input-objects", + "/en/v4/input_object/acceptenterpriseadministratorinvitationinput": "/en/graphql/reference/input-objects#acceptenterpriseadministratorinvitationinput", + "/en/v4/input_object/accepttopicsuggestioninput": "/en/graphql/reference/input-objects#accepttopicsuggestioninput", + "/en/v4/interface": "/en/graphql/reference/interfaces", + "/en/v4/interface/actor": "/en/graphql/reference/interfaces#actor", + "/en/v4/interface/assignable": "/en/graphql/reference/interfaces#assignable", + "/en/v4/mutation": "/en/graphql/reference/mutations", + "/en/v4/mutation/acceptenterpriseadministratorinvitation": "/en/graphql/reference/mutations#acceptenterpriseadministratorinvitation", + "/en/v4/mutation/accepttopicsuggestion": "/en/graphql/reference/mutations#accepttopicsuggestion", + "/en/v4/object": "/en/graphql/reference/objects", + "/en/v4/object/actorlocation": "/en/graphql/reference/objects#actorlocation", + "/en/v4/object/addedtoprojectevent": "/en/graphql/reference/objects#addedtoprojectevent", + "/en/v4/previews": "/en/graphql/overview/schema-previews", + "/en/v4/public_schema": "/en/graphql/overview/public-schema", + "/en/v4/query": "/en/graphql/reference/queries", + "/en/v4/reference": "/en/graphql/reference", + "/en/v4/scalar": "/en/graphql/reference/scalars", + "/en/v4/scalar/boolean": "/en/graphql/reference/scalars#boolean", + "/en/v4/scalar/date": "/en/graphql/reference/scalars#date", + "/en/v4/union": "/en/graphql/reference/unions", + "/en/v4/union/assignee": "/en/graphql/reference/unions#assignee", + "/en/v4/union/auditentryactor": "/en/graphql/reference/unions#auditentryactor", "/enterprise/2.18/user/v4/enum": "/en/enterprise/2.18/user/graphql/reference/enums", "/enterprise/2.18/user/v4/enum/auditlogorderfield": "/en/enterprise/2.18/user/graphql/reference/enums#auditlogorderfield", "/enterprise/2.18/user/v4/enum/checkannotationlevel": "/en/enterprise/2.18/user/graphql/reference/enums#checkannotationlevel", @@ -367,30 +367,30 @@ "/enterprise/v4/union": "/en/enterprise-server/graphql/reference/unions", "/enterprise/v4/union/assignee": "/en/enterprise-server/graphql/reference/unions#assignee", "/enterprise/v4/union/auditentryactor": "/en/enterprise-server/graphql/reference/unions#auditentryactor", - "/v4/enum": "/en/free-pro-team@latest/graphql/reference/enums", - "/v4/enum/auditlogorderfield": "/en/free-pro-team@latest/graphql/reference/enums#auditlogorderfield", - "/v4/enum/checkannotationlevel": "/en/free-pro-team@latest/graphql/reference/enums#checkannotationlevel", - "/v4/guides": "/en/free-pro-team@latest/graphql/guides", - "/v4/input_object": "/en/free-pro-team@latest/graphql/reference/input-objects", - "/v4/input_object/acceptenterpriseadministratorinvitationinput": "/en/free-pro-team@latest/graphql/reference/input-objects#acceptenterpriseadministratorinvitationinput", - "/v4/input_object/accepttopicsuggestioninput": "/en/free-pro-team@latest/graphql/reference/input-objects#accepttopicsuggestioninput", - "/v4/interface": "/en/free-pro-team@latest/graphql/reference/interfaces", - "/v4/interface/actor": "/en/free-pro-team@latest/graphql/reference/interfaces#actor", - "/v4/interface/assignable": "/en/free-pro-team@latest/graphql/reference/interfaces#assignable", - "/v4/mutation": "/en/free-pro-team@latest/graphql/reference/mutations", - "/v4/mutation/acceptenterpriseadministratorinvitation": "/en/free-pro-team@latest/graphql/reference/mutations#acceptenterpriseadministratorinvitation", - "/v4/mutation/accepttopicsuggestion": "/en/free-pro-team@latest/graphql/reference/mutations#accepttopicsuggestion", - "/v4/object": "/en/free-pro-team@latest/graphql/reference/objects", - "/v4/object/actorlocation": "/en/free-pro-team@latest/graphql/reference/objects#actorlocation", - "/v4/object/addedtoprojectevent": "/en/free-pro-team@latest/graphql/reference/objects#addedtoprojectevent", - "/v4/previews": "/en/free-pro-team@latest/graphql/overview/schema-previews", - "/v4/public_schema": "/en/free-pro-team@latest/graphql/overview/public-schema", - "/v4/query": "/en/free-pro-team@latest/graphql/reference/queries", - "/v4/reference": "/en/free-pro-team@latest/graphql/reference", - "/v4/scalar": "/en/free-pro-team@latest/graphql/reference/scalars", - "/v4/scalar/boolean": "/en/free-pro-team@latest/graphql/reference/scalars#boolean", - "/v4/scalar/date": "/en/free-pro-team@latest/graphql/reference/scalars#date", - "/v4/union": "/en/free-pro-team@latest/graphql/reference/unions", - "/v4/union/assignee": "/en/free-pro-team@latest/graphql/reference/unions#assignee", - "/v4/union/auditentryactor": "/en/free-pro-team@latest/graphql/reference/unions#auditentryactor" + "/v4/enum": "/en/graphql/reference/enums", + "/v4/enum/auditlogorderfield": "/en/graphql/reference/enums#auditlogorderfield", + "/v4/enum/checkannotationlevel": "/en/graphql/reference/enums#checkannotationlevel", + "/v4/guides": "/en/graphql/guides", + "/v4/input_object": "/en/graphql/reference/input-objects", + "/v4/input_object/acceptenterpriseadministratorinvitationinput": "/en/graphql/reference/input-objects#acceptenterpriseadministratorinvitationinput", + "/v4/input_object/accepttopicsuggestioninput": "/en/graphql/reference/input-objects#accepttopicsuggestioninput", + "/v4/interface": "/en/graphql/reference/interfaces", + "/v4/interface/actor": "/en/graphql/reference/interfaces#actor", + "/v4/interface/assignable": "/en/graphql/reference/interfaces#assignable", + "/v4/mutation": "/en/graphql/reference/mutations", + "/v4/mutation/acceptenterpriseadministratorinvitation": "/en/graphql/reference/mutations#acceptenterpriseadministratorinvitation", + "/v4/mutation/accepttopicsuggestion": "/en/graphql/reference/mutations#accepttopicsuggestion", + "/v4/object": "/en/graphql/reference/objects", + "/v4/object/actorlocation": "/en/graphql/reference/objects#actorlocation", + "/v4/object/addedtoprojectevent": "/en/graphql/reference/objects#addedtoprojectevent", + "/v4/previews": "/en/graphql/overview/schema-previews", + "/v4/public_schema": "/en/graphql/overview/public-schema", + "/v4/query": "/en/graphql/reference/queries", + "/v4/reference": "/en/graphql/reference", + "/v4/scalar": "/en/graphql/reference/scalars", + "/v4/scalar/boolean": "/en/graphql/reference/scalars#boolean", + "/v4/scalar/date": "/en/graphql/reference/scalars#date", + "/v4/union": "/en/graphql/reference/unions", + "/v4/union/assignee": "/en/graphql/reference/unions#assignee", + "/v4/union/auditentryactor": "/en/graphql/reference/unions#auditentryactor" } diff --git a/tests/fixtures/rest-redirects.json b/tests/fixtures/rest-redirects.json index d6b4e852f2..7452894547 100644 --- a/tests/fixtures/rest-redirects.json +++ b/tests/fixtures/rest-redirects.json @@ -385,35 +385,35 @@ "/en/enterprise/2.21/v3/users/gpg_keys": "/en/enterprise-server@2.21/rest/reference/users#gpg-keys", "/en/enterprise/2.21/v3/users": "/en/enterprise-server@2.21/rest/reference/users", "/en/enterprise/2.21/v3/users/keys": "/en/enterprise-server@2.21/rest/reference/users#keys", - "/v3/actions/artifacts": "/en/free-pro-team@latest/rest/reference/actions#artifacts", - "/v3/actions": "/en/free-pro-team@latest/rest/reference/actions", - "/v3/actions/secrets": "/en/free-pro-team@latest/rest/reference/actions#secrets", - "/v3/actions/self-hosted-runners": "/en/free-pro-team@latest/rest/reference/actions#self-hosted-runners", - "/v3/actions/self_hosted_runners": "/en/free-pro-team@latest/rest/reference/actions#self-hosted-runners", - "/v3/actions/workflow-jobs": "/en/free-pro-team@latest/rest/reference/actions#workflow-jobs", - "/v3/actions/workflow-runs": "/en/free-pro-team@latest/rest/reference/actions#workflow-runs", - "/v3/actions/workflows": "/en/free-pro-team@latest/rest/reference/actions#workflows", - "/v3/activity/event_types": "/en/free-pro-team@latest/developers/webhooks-and-events/github-event-types", - "/v3/activity/events/types": "/en/free-pro-team@latest/developers/webhooks-and-events/webhook-events-and-payloads", - "/v3/activity/events": "/en/free-pro-team@latest/rest/reference/activity#events", - "/v3/activity/feeds": "/en/free-pro-team@latest/rest/reference/activity#feeds", - "/v3/activity": "/en/free-pro-team@latest/rest/reference/activity", - "/v3/activity/notifications": "/en/free-pro-team@latest/rest/reference/activity#notifications", - "/v3/activity/starring": "/en/free-pro-team@latest/rest/reference/activity#starring", - "/v3/activity/watching": "/en/free-pro-team@latest/rest/reference/activity#watching", - "/v3/apps/available-endpoints": "/en/free-pro-team@latest/rest/overview/endpoints-available-for-github-apps", - "/v3/apps": "/en/free-pro-team@latest/rest/reference/apps", - "/v3/apps/installations": "/en/free-pro-team@latest/rest/reference/apps#installations", - "/v3/apps/marketplace": "/en/free-pro-team@latest/rest/reference/apps#marketplace", - "/v3/apps/oauth_applications": "/en/free-pro-team@latest/rest/reference/apps#oauth-applications", - "/v3/apps/permissions": "/en/free-pro-team@latest/rest/reference/permissions-required-for-github-apps", - "/v3/checks": "/en/free-pro-team@latest/rest/reference/checks", - "/v3/checks/runs": "/en/free-pro-team@latest/rest/reference/checks#runs", - "/v3/checks/suites": "/en/free-pro-team@latest/rest/reference/checks#suites", - "/v3/code-scanning": "/en/free-pro-team@latest/rest/reference/code-scanning", - "/v3/codes_of_conduct": "/en/free-pro-team@latest/rest/reference/codes-of-conduct", - "/v3/emojis": "/en/free-pro-team@latest/rest/reference/emojis", - "/v3/enterprise-admin": "/en/free-pro-team@latest/rest/reference/enterprise-admin", + "/v3/actions/artifacts": "/en/rest/reference/actions#artifacts", + "/v3/actions": "/en/rest/reference/actions", + "/v3/actions/secrets": "/en/rest/reference/actions#secrets", + "/v3/actions/self-hosted-runners": "/en/rest/reference/actions#self-hosted-runners", + "/v3/actions/self_hosted_runners": "/en/rest/reference/actions#self-hosted-runners", + "/v3/actions/workflow-jobs": "/en/rest/reference/actions#workflow-jobs", + "/v3/actions/workflow-runs": "/en/rest/reference/actions#workflow-runs", + "/v3/actions/workflows": "/en/rest/reference/actions#workflows", + "/v3/activity/event_types": "/en/developers/webhooks-and-events/github-event-types", + "/v3/activity/events/types": "/en/developers/webhooks-and-events/webhook-events-and-payloads", + "/v3/activity/events": "/en/rest/reference/activity#events", + "/v3/activity/feeds": "/en/rest/reference/activity#feeds", + "/v3/activity": "/en/rest/reference/activity", + "/v3/activity/notifications": "/en/rest/reference/activity#notifications", + "/v3/activity/starring": "/en/rest/reference/activity#starring", + "/v3/activity/watching": "/en/rest/reference/activity#watching", + "/v3/apps/available-endpoints": "/en/rest/overview/endpoints-available-for-github-apps", + "/v3/apps": "/en/rest/reference/apps", + "/v3/apps/installations": "/en/rest/reference/apps#installations", + "/v3/apps/marketplace": "/en/rest/reference/apps#marketplace", + "/v3/apps/oauth_applications": "/en/rest/reference/apps#oauth-applications", + "/v3/apps/permissions": "/en/rest/reference/permissions-required-for-github-apps", + "/v3/checks": "/en/rest/reference/checks", + "/v3/checks/runs": "/en/rest/reference/checks#runs", + "/v3/checks/suites": "/en/rest/reference/checks#suites", + "/v3/code-scanning": "/en/rest/reference/code-scanning", + "/v3/codes_of_conduct": "/en/rest/reference/codes-of-conduct", + "/v3/emojis": "/en/rest/reference/emojis", + "/v3/enterprise-admin": "/en/rest/reference/enterprise-admin", "/v3/enterprise-admin/admin_stats": "/en/enterprise-server/rest/reference/enterprise-admin#admin-stats", "/v3/enterprise-admin/global_webhooks": "/en/enterprise-server/rest/reference/enterprise-admin#global-webhooks", "/v3/enterprise-admin/ldap": "/en/enterprise-server/rest/reference/enterprise-admin#ldap", @@ -424,83 +424,83 @@ "/v3/enterprise-admin/pre_receive_hooks": "/en/enterprise-server/rest/reference/enterprise-admin#pre-receive-hooks", "/v3/enterprise-admin/search_indexing": "/en/enterprise-server/rest/reference/enterprise-admin#search-indexing", "/v3/enterprise-admin/users": "/en/enterprise-server/rest/reference/enterprise-admin#users", - "/v3/gists/comments": "/en/free-pro-team@latest/rest/reference/gists#comments", - "/v3/gists": "/en/free-pro-team@latest/rest/reference/gists", - "/v3/git/blobs": "/en/free-pro-team@latest/rest/reference/git#blobs", - "/v3/git/commits": "/en/free-pro-team@latest/rest/reference/git#commits", - "/v3/git": "/en/free-pro-team@latest/rest/reference/git", - "/v3/git/refs": "/en/free-pro-team@latest/rest/reference/git#refs", - "/v3/git/tags": "/en/free-pro-team@latest/rest/reference/git#tags", - "/v3/git/trees": "/en/free-pro-team@latest/rest/reference/git#trees", - "/v3/gitignore": "/en/free-pro-team@latest/rest/reference/gitignore", - "/v3/interactions": "/en/free-pro-team@latest/rest/reference/interactions", - "/v3/interactions/orgs": "/en/free-pro-team@latest/rest/reference/interactions#orgs", - "/v3/interactions/repos": "/en/free-pro-team@latest/rest/reference/interactions#repos", - "/v3/issues/assignees": "/en/free-pro-team@latest/rest/reference/issues#assignees", - "/v3/issues/comments": "/en/free-pro-team@latest/rest/reference/issues#comments", - "/v3/issues/events": "/en/free-pro-team@latest/rest/reference/issues#events", - "/v3/issues": "/en/free-pro-team@latest/rest/reference/issues", - "/v3/issues/issue-event-types": "/en/free-pro-team@latest/developers/webhooks-and-events/issue-event-types", - "/v3/issues/labels": "/en/free-pro-team@latest/rest/reference/issues#labels", - "/v3/issues/milestones": "/en/free-pro-team@latest/rest/reference/issues#milestones", - "/v3/issues/timeline": "/en/free-pro-team@latest/rest/reference/issues#timeline", - "/v3/licenses": "/en/free-pro-team@latest/rest/reference/licenses", - "/v3/markdown": "/en/free-pro-team@latest/rest/reference/markdown", - "/v3/meta": "/en/free-pro-team@latest/rest/reference/meta", - "/v3/migrations": "/en/free-pro-team@latest/rest/reference/migrations", - "/v3/migrations/orgs": "/en/free-pro-team@latest/rest/reference/migrations#orgs", - "/v3/migrations/source_imports": "/en/free-pro-team@latest/rest/reference/migrations#source-imports", - "/v3/migrations/users": "/en/free-pro-team@latest/rest/reference/migrations#users", + "/v3/gists/comments": "/en/rest/reference/gists#comments", + "/v3/gists": "/en/rest/reference/gists", + "/v3/git/blobs": "/en/rest/reference/git#blobs", + "/v3/git/commits": "/en/rest/reference/git#commits", + "/v3/git": "/en/rest/reference/git", + "/v3/git/refs": "/en/rest/reference/git#refs", + "/v3/git/tags": "/en/rest/reference/git#tags", + "/v3/git/trees": "/en/rest/reference/git#trees", + "/v3/gitignore": "/en/rest/reference/gitignore", + "/v3/interactions": "/en/rest/reference/interactions", + "/v3/interactions/orgs": "/en/rest/reference/interactions#orgs", + "/v3/interactions/repos": "/en/rest/reference/interactions#repos", + "/v3/issues/assignees": "/en/rest/reference/issues#assignees", + "/v3/issues/comments": "/en/rest/reference/issues#comments", + "/v3/issues/events": "/en/rest/reference/issues#events", + "/v3/issues": "/en/rest/reference/issues", + "/v3/issues/issue-event-types": "/en/developers/webhooks-and-events/issue-event-types", + "/v3/issues/labels": "/en/rest/reference/issues#labels", + "/v3/issues/milestones": "/en/rest/reference/issues#milestones", + "/v3/issues/timeline": "/en/rest/reference/issues#timeline", + "/v3/licenses": "/en/rest/reference/licenses", + "/v3/markdown": "/en/rest/reference/markdown", + "/v3/meta": "/en/rest/reference/meta", + "/v3/migrations": "/en/rest/reference/migrations", + "/v3/migrations/orgs": "/en/rest/reference/migrations#orgs", + "/v3/migrations/source_imports": "/en/rest/reference/migrations#source-imports", + "/v3/migrations/users": "/en/rest/reference/migrations#users", "/v3/oauth_authorizations": "/en/enterprise-server/rest/reference/oauth-authorizations", - "/v3/orgs/blocking": "/en/free-pro-team@latest/rest/reference/orgs#blocking", - "/v3/orgs/hooks": "/en/free-pro-team@latest/rest/reference/orgs#webhooks", - "/v3/orgs": "/en/free-pro-team@latest/rest/reference/orgs", - "/v3/orgs/members": "/en/free-pro-team@latest/rest/reference/orgs#members", - "/v3/orgs/migrations": "/en/free-pro-team@latest/rest/reference/orgs#migrations", - "/v3/orgs/outside_collaborators": "/en/free-pro-team@latest/rest/reference/orgs#outside-collaborators", + "/v3/orgs/blocking": "/en/rest/reference/orgs#blocking", + "/v3/orgs/hooks": "/en/rest/reference/orgs#webhooks", + "/v3/orgs": "/en/rest/reference/orgs", + "/v3/orgs/members": "/en/rest/reference/orgs#members", + "/v3/orgs/migrations": "/en/rest/reference/orgs#migrations", + "/v3/orgs/outside_collaborators": "/en/rest/reference/orgs#outside-collaborators", "/v3/orgs/pre_receive_hooks": "/en/enterprise-server/rest/reference/enterprise-admin#organization-pre-receive-hooks", - "/v3/orgs/teams": "/en/free-pro-team@latest/rest/reference/orgs#teams", - "/v3/projects/cards": "/en/free-pro-team@latest/rest/reference/projects#cards", - "/v3/projects/collaborators": "/en/free-pro-team@latest/rest/reference/projects#collaborators", - "/v3/projects/columns": "/en/free-pro-team@latest/rest/reference/projects#columns", - "/v3/projects": "/en/free-pro-team@latest/rest/reference/projects", - "/v3/pulls/comments": "/en/free-pro-team@latest/rest/reference/pulls#comments", - "/v3/pulls": "/en/free-pro-team@latest/rest/reference/pulls", - "/v3/pulls/review_requests": "/en/free-pro-team@latest/rest/reference/pulls#review-requests", - "/v3/pulls/reviews": "/en/free-pro-team@latest/rest/reference/pulls#reviews", - "/v3/rate_limit": "/en/free-pro-team@latest/rest/reference/rate-limit", - "/v3/reactions": "/en/free-pro-team@latest/rest/reference/reactions", - "/v3/repos/branches": "/en/free-pro-team@latest/rest/reference/repos#branches", - "/v3/repos/collaborators": "/en/free-pro-team@latest/rest/reference/repos#collaborators", - "/v3/repos/comments": "/en/free-pro-team@latest/rest/reference/repos#comments", - "/v3/repos/commits": "/en/free-pro-team@latest/rest/reference/repos#commits", - "/v3/repos/community": "/en/free-pro-team@latest/rest/reference/repos#community", - "/v3/repos/contents": "/en/free-pro-team@latest/rest/reference/repos#contents", - "/v3/repos/deployments": "/en/free-pro-team@latest/rest/reference/repos#deployments", - "/v3/repos/downloads": "/en/free-pro-team@latest/rest/reference/repos#downloads", - "/v3/repos/forks": "/en/free-pro-team@latest/rest/reference/repos#forks", - "/v3/repos/hooks": "/en/free-pro-team@latest/rest/reference/repos#webhooks", - "/v3/repos": "/en/free-pro-team@latest/rest/reference/repos", - "/v3/repos/invitations": "/en/free-pro-team@latest/rest/reference/repos#invitations", - "/v3/repos/keys": "/en/free-pro-team@latest/rest/reference/repos#keys", - "/v3/repos/merging": "/en/free-pro-team@latest/rest/reference/repos#merging", - "/v3/repos/pages": "/en/free-pro-team@latest/rest/reference/repos#pages", + "/v3/orgs/teams": "/en/rest/reference/orgs#teams", + "/v3/projects/cards": "/en/rest/reference/projects#cards", + "/v3/projects/collaborators": "/en/rest/reference/projects#collaborators", + "/v3/projects/columns": "/en/rest/reference/projects#columns", + "/v3/projects": "/en/rest/reference/projects", + "/v3/pulls/comments": "/en/rest/reference/pulls#comments", + "/v3/pulls": "/en/rest/reference/pulls", + "/v3/pulls/review_requests": "/en/rest/reference/pulls#review-requests", + "/v3/pulls/reviews": "/en/rest/reference/pulls#reviews", + "/v3/rate_limit": "/en/rest/reference/rate-limit", + "/v3/reactions": "/en/rest/reference/reactions", + "/v3/repos/branches": "/en/rest/reference/repos#branches", + "/v3/repos/collaborators": "/en/rest/reference/repos#collaborators", + "/v3/repos/comments": "/en/rest/reference/repos#comments", + "/v3/repos/commits": "/en/rest/reference/repos#commits", + "/v3/repos/community": "/en/rest/reference/repos#community", + "/v3/repos/contents": "/en/rest/reference/repos#contents", + "/v3/repos/deployments": "/en/rest/reference/repos#deployments", + "/v3/repos/downloads": "/en/rest/reference/repos#downloads", + "/v3/repos/forks": "/en/rest/reference/repos#forks", + "/v3/repos/hooks": "/en/rest/reference/repos#webhooks", + "/v3/repos": "/en/rest/reference/repos", + "/v3/repos/invitations": "/en/rest/reference/repos#invitations", + "/v3/repos/keys": "/en/rest/reference/repos#keys", + "/v3/repos/merging": "/en/rest/reference/repos#merging", + "/v3/repos/pages": "/en/rest/reference/repos#pages", "/v3/repos/pre_receive_hooks": "/en/enterprise-server/rest/reference/enterprise-admin#repository-pre-receive-hooks", - "/v3/repos/releases": "/en/free-pro-team@latest/rest/reference/repos#releases", - "/v3/repos/statistics": "/en/free-pro-team@latest/rest/reference/repos#statistics", - "/v3/repos/statuses": "/en/free-pro-team@latest/rest/reference/repos#statuses", - "/v3/repos/traffic": "/en/free-pro-team@latest/rest/reference/repos#traffic", - "/v3/scim": "/en/free-pro-team@latest/rest/reference/scim", - "/v3/search": "/en/free-pro-team@latest/rest/reference/search", - "/v3/teams/discussion_comments": "/en/free-pro-team@latest/rest/reference/teams#discussion-comments", - "/v3/teams/discussions": "/en/free-pro-team@latest/rest/reference/teams#discussions", - "/v3/teams": "/en/free-pro-team@latest/rest/reference/teams", - "/v3/teams/members": "/en/free-pro-team@latest/rest/reference/teams#members", - "/v3/teams/team_sync": "/en/free-pro-team@latest/rest/reference/teams#team-sync", - "/v3/users/blocking": "/en/free-pro-team@latest/rest/reference/users#blocking", - "/v3/users/emails": "/en/free-pro-team@latest/rest/reference/users#emails", - "/v3/users/followers": "/en/free-pro-team@latest/rest/reference/users#followers", - "/v3/users/gpg_keys": "/en/free-pro-team@latest/rest/reference/users#gpg-keys", - "/v3/users": "/en/free-pro-team@latest/rest/reference/users", - "/v3/users/keys": "/en/free-pro-team@latest/rest/reference/users#keys" + "/v3/repos/releases": "/en/rest/reference/repos#releases", + "/v3/repos/statistics": "/en/rest/reference/repos#statistics", + "/v3/repos/statuses": "/en/rest/reference/repos#statuses", + "/v3/repos/traffic": "/en/rest/reference/repos#traffic", + "/v3/scim": "/en/rest/reference/scim", + "/v3/search": "/en/rest/reference/search", + "/v3/teams/discussion_comments": "/en/rest/reference/teams#discussion-comments", + "/v3/teams/discussions": "/en/rest/reference/teams#discussions", + "/v3/teams": "/en/rest/reference/teams", + "/v3/teams/members": "/en/rest/reference/teams#members", + "/v3/teams/team_sync": "/en/rest/reference/teams#team-sync", + "/v3/users/blocking": "/en/rest/reference/users#blocking", + "/v3/users/emails": "/en/rest/reference/users#emails", + "/v3/users/followers": "/en/rest/reference/users#followers", + "/v3/users/gpg_keys": "/en/rest/reference/users#gpg-keys", + "/v3/users": "/en/rest/reference/users", + "/v3/users/keys": "/en/rest/reference/users#keys" } diff --git a/tests/rendering/breadcrumbs.js b/tests/rendering/breadcrumbs.js index 4d5f4aa955..0675412077 100644 --- a/tests/rendering/breadcrumbs.js +++ b/tests/rendering/breadcrumbs.js @@ -52,13 +52,13 @@ describe('breadcrumbs', () => { test('English breadcrumbs link to English pages', async () => { const $ = await getDOM('/en/github/getting-started-with-github') const $breadcrumbs = $('.breadcrumbs a') - expect($breadcrumbs.eq(0).attr('href')).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) + expect($breadcrumbs.eq(0).attr('href')).toBe(`/en/github`) }) test('localized breadcrumbs link to localize pages', async () => { const $ = await getDOM('/ja/github/getting-started-with-github') const $breadcrumbs = $('.breadcrumbs a') - expect($breadcrumbs.eq(0).attr('href')).toBe(`/ja/${nonEnterpriseDefaultVersion}/github`) + expect($breadcrumbs.eq(0).attr('href')).toBe(`/ja/github`) }) }) @@ -88,7 +88,7 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github?json=breadcrumbs') const expected = { product: { - href: `/en/${nonEnterpriseDefaultVersion}/github`, + href: `/en/github`, title: 'GitHub.com' } } @@ -99,11 +99,11 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github?json=breadcrumbs') const expected = { product: { - href: `/en/${nonEnterpriseDefaultVersion}/github`, + href: `/en/github`, title: 'GitHub.com' }, category: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github`, + href: `/en/github/authenticating-to-github`, title: 'Authentication' } } @@ -114,15 +114,15 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github/keeping-your-account-and-data-secure?json=breadcrumbs') const expected = { product: { - href: `/en/${nonEnterpriseDefaultVersion}/github`, + href: `/en/github`, title: 'GitHub.com' }, category: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github`, + href: `/en/github/authenticating-to-github`, title: 'Authentication' }, maptopic: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github/keeping-your-account-and-data-secure`, + href: `/en/github/authenticating-to-github/keeping-your-account-and-data-secure`, title: 'Keeping your account and data secure' } } @@ -133,19 +133,19 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github/creating-a-strong-password?json=breadcrumbs') const expected = { product: { - href: `/en/${nonEnterpriseDefaultVersion}/github`, + href: `/en/github`, title: 'GitHub.com' }, category: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github`, + href: `/en/github/authenticating-to-github`, title: 'Authentication' }, maptopic: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github/keeping-your-account-and-data-secure`, + href: `/en/github/authenticating-to-github/keeping-your-account-and-data-secure`, title: 'Keeping your account and data secure' }, article: { - href: `/en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github/creating-a-strong-password`, + href: `/en/github/authenticating-to-github/creating-a-strong-password`, title: 'Creating a strong password' } } @@ -156,15 +156,15 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/github/site-policy/github-privacy-statement?json=breadcrumbs') const expected = { product: { - href: `/en/${nonEnterpriseDefaultVersion}/github`, + href: `/en/github`, title: 'GitHub.com' }, category: { - href: `/en/${nonEnterpriseDefaultVersion}/github/site-policy`, + href: `/en/github/site-policy`, title: 'Site policy' }, article: { - href: `/en/${nonEnterpriseDefaultVersion}/github/site-policy/github-privacy-statement`, + href: `/en/github/site-policy/github-privacy-statement`, title: 'GitHub Privacy Statement' } } diff --git a/tests/rendering/header.js b/tests/rendering/header.js index 3847ed2bf0..8460c5d960 100644 --- a/tests/rendering/header.js +++ b/tests/rendering/header.js @@ -22,7 +22,7 @@ describe('header', () => { describe('language links', () => { test('lead to the same page in a different language', async () => { const $ = await getDOM('/en/github/administering-a-repository/enabling-required-status-checks') - expect($(`#languages-selector a[href="/ja/${nonEnterpriseDefaultVersion}/github/administering-a-repository/enabling-required-status-checks"]`).length).toBe(1) + expect($(`#languages-selector a[href="/ja/github/administering-a-repository/enabling-required-status-checks"]`).length).toBe(1) }) test('display the native name and the English name for each translated language', async () => { @@ -68,7 +68,7 @@ describe('header', () => { test('include github and admin, and emphasize the current product', async () => { const $ = await getDOM('/en/articles/enabling-required-status-checks') - const github = $(`#homepages a.active[href="/en/${nonEnterpriseDefaultVersion}/github"]`) + const github = $(`#homepages a.active[href="/en/github"]`) expect(github.length).toBe(1) expect(github.text().trim()).toBe('GitHub.com') expect(github.attr('class').includes('active')).toBe(true) @@ -82,15 +82,15 @@ describe('header', () => { test('point to homepages in the current page\'s language', async () => { const $ = await getDOM('/ja/articles/enabling-required-status-checks') - expect($(`#homepages a.active[href="/ja/${nonEnterpriseDefaultVersion}/github"]`).length).toBe(1) + expect($(`#homepages a.active[href="/ja/github"]`).length).toBe(1) expect($(`#homepages a[href="/ja/enterprise-server@${latest}/admin"]`).length).toBe(1) }) test('emphasizes the product that corresponds to the current page', async () => { const $ = await getDOM(`/en/enterprise/${oldestSupported}/user/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address`) expect($(`#homepages a.active[href="/en/enterprise-server@${latest}/admin"]`).length).toBe(0) - expect($(`#homepages a[href="/en/${nonEnterpriseDefaultVersion}/github"]`).length).toBe(1) - expect($(`#homepages a.active[href="/en/${nonEnterpriseDefaultVersion}/github"]`).length).toBe(1) + expect($(`#homepages a[href="/en/github"]`).length).toBe(1) + expect($(`#homepages a.active[href="/en/github"]`).length).toBe(1) }) }) }) diff --git a/tests/rendering/server.js b/tests/rendering/server.js index eeafe78c7b..2ceec26816 100644 --- a/tests/rendering/server.js +++ b/tests/rendering/server.js @@ -214,7 +214,7 @@ describe('server', () => { test('displays links to categories on product TOCs', async () => { const $ = await getDOM('/en/github') - expect($(`article a[href="/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github"]`)).toHaveLength(1) + expect($(`article a[href="/en/github/getting-started-with-github"]`)).toHaveLength(1) }) describe('autogenerated mini TOCs', () => { @@ -296,7 +296,7 @@ describe('server', () => { test('dotcom articles on dotcom have links that include "en"', async () => { const $ = await getDOM('/en/articles/set-up-git') - expect($(`a[href="/en/${nonEnterpriseDefaultVersion}/articles/managing-files-on-github"]`).length).toBe(1) + expect($(`a[href="/en/articles/managing-files-on-github"]`).length).toBe(1) }) test('dotcom articles on dotcom have Enterprise Admin links with latest GHE version', async () => { @@ -316,12 +316,12 @@ describe('server', () => { test('dotcom-only links on GHE are dotcom-only', async () => { const $ = await getDOM(`${latestEnterprisePath}/github/setting-up-and-managing-your-github-profile/sending-your-github-enterprise-server-contributions-to-your-githubcom-profile`) - expect($(`article a[href="/en/${nonEnterpriseDefaultVersion}/articles/github-privacy-statement"]`).length).toBe(1) + expect($(`article a[href="/en/articles/github-privacy-statement"]`).length).toBe(1) }) test('desktop links on GHE are dotcom-only', async () => { const $ = await getDOM(`${latestEnterprisePath}/github/getting-started-with-github/set-up-git`) - expect($(`article a[href="/en/${nonEnterpriseDefaultVersion}/desktop/installing-and-configuring-github-desktop"]`).length).toBe(1) + expect($(`article a[href="/en/desktop/installing-and-configuring-github-desktop"]`).length).toBe(1) }) test('admin articles that link to non-admin articles have Enterprise user links', async () => { @@ -405,7 +405,7 @@ describe('server', () => { test('redirects old articles to their slugified URL', async () => { const res = await get('/articles/about-github-s-ip-addresses') - expect(res.text).toBe(`Moved Permanently. Redirecting to /en/${nonEnterpriseDefaultVersion}/github/authenticating-to-github/about-githubs-ip-addresses`) + expect(res.text).toBe(`Moved Permanently. Redirecting to /en/github/authenticating-to-github/about-githubs-ip-addresses`) }) test('redirects / to /en', async () => { @@ -444,13 +444,13 @@ describe('server', () => { describe('categories and map topics', () => { test('adds links to categories on the dotcom homepage', async () => { const $ = await getDOM('/en/github') - expect($(`article a[href="/en/${nonEnterpriseDefaultVersion}/github/managing-large-files"]`).length).toBe(1) + expect($(`article a[href="/en/github/managing-large-files"]`).length).toBe(1) expect($('article a[href="#managing-large-files"]').length).toBe(0) }) test('adds links to map topics on a category homepage', async () => { const $ = await getDOM('/en/github/setting-up-and-managing-your-github-user-account') - expect($(`article a[href="/en/${nonEnterpriseDefaultVersion}/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings"]`).length).toBe(1) + expect($(`article a[href="/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings"]`).length).toBe(1) expect($('article a[href="#managing-user-account-settings"]').length).toBe(0) }) @@ -461,7 +461,7 @@ describe('server', () => { test('map topic renders with h2 links to articles', async () => { const $ = await getDOM('/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings') - expect($(`a[href="/en/${nonEnterpriseDefaultVersion}/github/setting-up-and-managing-your-github-user-account/changing-your-github-username"] h2`).length).toBe(1) + expect($(`a[href="/en/github/setting-up-and-managing-your-github-user-account/changing-your-github-username"] h2`).length).toBe(1) }) test('map topic renders with one intro for every h2', async () => { @@ -572,26 +572,26 @@ describe('GitHub Enterprise URLs', () => { describe('GitHub Desktop URLs', () => { test('renders the GitHub Desktop homepage with correct links', async () => { const $ = await getDOM('/en/desktop') - expect($(`article a[href^="/en/${nonEnterpriseDefaultVersion}/desktop/"]`).length).toBeGreaterThan(1) + expect($(`article a[href^="/en/desktop/"]`).length).toBeGreaterThan(1) }) test('renders a Desktop category with expected links', async () => { const $ = await getDOM('/en/desktop/installing-and-configuring-github-desktop') - expect($(`article a[href^="/en/${nonEnterpriseDefaultVersion}/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) + expect($(`article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) }) test('renders a Desktop map topic', async () => { const $ = await getDOM('/en/desktop/installing-and-configuring-github-desktop/installing-and-authenticating-to-github-desktop') - expect($(`article a[href^="/en/${nonEnterpriseDefaultVersion}/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) + expect($(`article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) }) test('renders a Desktop article within a map topic', async () => { - const res = await get(`/en/${nonEnterpriseDefaultVersion}/desktop/installing-and-configuring-github-desktop/installing-github-desktop`) + const res = await get(`/en/desktop/installing-and-configuring-github-desktop/installing-github-desktop`) expect(res.statusCode).toBe(200) }) test('renders the Desktop homepage in Japanese', async () => { - const res = await get(`/ja/${nonEnterpriseDefaultVersion}/desktop`) + const res = await get(`/ja/desktop`) expect(res.statusCode).toBe(200) }) }) @@ -743,7 +743,7 @@ describe('static routes', () => { }) describe('index pages', () => { - const nonEnterpriseOnlyPath = `/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github/verifying-your-email-address` + const nonEnterpriseOnlyPath = `/en/github/getting-started-with-github/verifying-your-email-address` test('includes dotcom-only links in dotcom TOC', async () => { const $ = await getDOM('/en/github/getting-started-with-github') diff --git a/tests/rendering/sidebar.js b/tests/rendering/sidebar.js index 813018b8a9..5fbe8493cb 100644 --- a/tests/rendering/sidebar.js +++ b/tests/rendering/sidebar.js @@ -31,7 +31,7 @@ describe('sidebar', () => { }) test('adds an `is-current-page` class to the sidebar link to the current page', async () => { - const url = `/en/${nonEnterpriseDefaultVersion}/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings` + const url = `/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings` const $ = await getDOM(url) expect($('.sidebar .is-current-page').length).toBe(1) expect($('.sidebar .is-current-page a').attr('href')).toContain(url) diff --git a/tests/routing/developer-site-redirects.js b/tests/routing/developer-site-redirects.js index d44d90360b..5560d97601 100644 --- a/tests/routing/developer-site-redirects.js +++ b/tests/routing/developer-site-redirects.js @@ -1,3 +1,4 @@ +const path = require('path') const { eachOfLimit } = require('async') const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const { get } = require('../helpers/supertest') @@ -22,7 +23,7 @@ describe('developer redirects', () => { test('graphql homepage', async () => { const res = await get('/v4') expect(res.statusCode).toBe(301) - const expectedFinalPath = `/en/${nonEnterpriseDefaultVersion}/graphql` + const expectedFinalPath = `/en/graphql` expect(res.headers.location).toBe(expectedFinalPath) }) @@ -36,7 +37,7 @@ describe('developer redirects', () => { test('graphql overview paths', async () => { const oldPath = '/v4/breaking_changes' - const newPath = `/${nonEnterpriseDefaultVersion}/graphql/overview/breaking-changes` + const newPath = `/graphql/overview/breaking-changes` const res = await get(oldPath) expect(res.statusCode).toBe(301) expect(res.headers.location).toBe(`/en${newPath}`) @@ -44,19 +45,19 @@ describe('developer redirects', () => { const enterpriseRes = await get(`/enterprise${oldPath}`, { followAllRedirects: true }) expect(enterpriseRes.statusCode).toBe(200) const finalPath = (new URL(enterpriseRes.request.url)).pathname - const expectedFinalPath = newPath.replace(nonEnterpriseDefaultVersion, `enterprise-server@${enterpriseServerReleases.latest}`) + const expectedFinalPath = path.join('/', `enterprise-server@${enterpriseServerReleases.latest}`, newPath) expect(finalPath).toBe(`/en${expectedFinalPath}`) }) test('graphql reference paths with child pages', async () => { const sclarRes = await get('/en/v4/scalar/boolean') expect(sclarRes.statusCode).toBe(301) - const sclarResFinalPath = `/en/${nonEnterpriseDefaultVersion}/graphql/reference/scalars#boolean` + const sclarResFinalPath = `/en/graphql/reference/scalars#boolean` expect(sclarRes.headers.location).toBe(sclarResFinalPath) const enumRes = await get('/en/v4/enum/searchtype') expect(enumRes.statusCode).toBe(301) - const enumResFinalPath = `/en/${nonEnterpriseDefaultVersion}/graphql/reference/enums#searchtype` + const enumResFinalPath = `/en/graphql/reference/enums#searchtype` expect(enumRes.headers.location).toBe(enumResFinalPath) }) }) @@ -65,21 +66,21 @@ describe('developer redirects', () => { let expectedFinalPath let res = await get('/v3') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/${nonEnterpriseDefaultVersion}/rest` + expectedFinalPath = `/en/rest` expect(res.headers.location).toBe(expectedFinalPath) // REST subresources like activity notifications don't have their own page // any more, so redirect to an anchor on the resource page res = await get('/en/v3/activity') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/${nonEnterpriseDefaultVersion}/rest/reference/activity` + expectedFinalPath = `/en/rest/reference/activity` expect(res.headers.location).toBe(expectedFinalPath) // REST subresources like activity notifications don't have their own page // any more, so redirect to an anchor on the resource page res = await get('/en/v3/activity/notifications') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/${nonEnterpriseDefaultVersion}/rest/reference/activity#notifications` + expectedFinalPath = `/en/rest/reference/activity#notifications` expect(res.headers.location).toBe(expectedFinalPath) // trailing slashes are handled separately by the `slashes` module; @@ -91,7 +92,7 @@ describe('developer redirects', () => { // non-reference redirects (e.g. guides) res = await get('/en/v3/guides/basics-of-authentication') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/${nonEnterpriseDefaultVersion}/rest/guides/basics-of-authentication` + expectedFinalPath = `/en/rest/guides/basics-of-authentication` expect(res.headers.location).toBe(expectedFinalPath) }) diff --git a/tests/routing/redirects.js b/tests/routing/redirects.js index 26ce2ba10d..a0185d6e66 100644 --- a/tests/routing/redirects.js +++ b/tests/routing/redirects.js @@ -34,10 +34,12 @@ describe('redirects', () => { languageCode: 'en' }) page.buildRedirects() - expect(page.redirects['/articles']).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) - expect(page.redirects['/en/articles']).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) - expect(page.redirects['/common-issues-and-questions']).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) - expect(page.redirects['/en/common-issues-and-questions']).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) + expect(page.redirects[`/en/${nonEnterpriseDefaultVersion}/github`]).toBe('/en/github') + expect(page.redirects['/articles']).toBe('/en/github') + expect(page.redirects['/en/articles']).toBe(`/en/github`) + expect(page.redirects[`/en/${nonEnterpriseDefaultVersion}/articles`]).toBe('/en/github') + expect(page.redirects['/common-issues-and-questions']).toBe('/en/github') + expect(page.redirects['/en/common-issues-and-questions']).toBe('/en/github') expect(page.redirects[`/en/enterprise/${enterpriseServerReleases.latest}/user/articles`]).toBe(`/en/enterprise-server@${enterpriseServerReleases.latest}/github`) expect(page.redirects[`/en/enterprise/${enterpriseServerReleases.latest}/user/common-issues-and-questions`]).toBe(`/en/enterprise-server@${enterpriseServerReleases.latest}/github`) }) @@ -49,7 +51,7 @@ describe('redirects', () => { languageCode: 'en' }) page.buildRedirects() - const expected = `/en/${nonEnterpriseDefaultVersion}/github/collaborating-with-issues-and-pull-requests/about-conversations-on-github` + const expected = `/en/github/collaborating-with-issues-and-pull-requests/about-conversations-on-github` expect(page.redirects['/en/articles/about-discussions-in-issues-and-pull-requests']).toBe(expected) }) @@ -125,7 +127,7 @@ describe('redirects', () => { test('redirect_from for renamed pages', async () => { const { res } = await get('/ja/desktop/contributing-to-projects/changing-a-remote-s-url-from-github-desktop') expect(res.statusCode).toBe(301) - const expected = `/ja/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop/changing-a-remotes-url-from-github-desktop` + const expected = `/ja/desktop/contributing-and-collaborating-using-github-desktop/changing-a-remotes-url-from-github-desktop` expect(res.headers.location).toBe(expected) }) }) @@ -332,7 +334,7 @@ describe('redirects', () => { }) describe('desktop guide', () => { - const desktopGuide = `/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request` + const desktopGuide = `/en/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request` const japaneseDesktopGuides = desktopGuide.replace('/en/', '/ja/') test('no language code redirects to english', async () => { diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index 6ff424b07c..aeb7931d51 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -57,7 +57,7 @@ describe('liquid helper tags', () => { test('link_with_intro tag', async () => { const template = '{% link_with_intro /contributing-and-collaborating-using-github-desktop %}' - const page = pageMap[`/en/${nonEnterpriseDefaultVersion}/desktop/contributing-and-collaborating-using-github-desktop`] + const page = pageMap[`/en/desktop/contributing-and-collaborating-using-github-desktop`] const expected = ` @@ -68,7 +68,7 @@ describe('liquid helper tags', () => { test('homepage_link_with_intro tag', async () => { const template = '{% homepage_link_with_intro /github/writing-on-github/basic-writing-and-formatting-syntax %}' - const page = pageMap[`/en/${nonEnterpriseDefaultVersion}/github/writing-on-github/basic-writing-and-formatting-syntax`] + const page = pageMap[`/en/github/writing-on-github/basic-writing-and-formatting-syntax`] const expected = ` diff --git a/tests/unit/page.js b/tests/unit/page.js index 95713465db..fd01830f97 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -86,8 +86,8 @@ describe('Page class', () => { test('rewrites links to include the current language prefix and version', async () => { const page = await Page.init(opts) const context = { - page: { version: nonEnterpriseDefaultVersion }, - currentVersion: nonEnterpriseDefaultVersion, + page: { version: `enterprise-server@${enterpriseServerReleases.latest}` }, + currentVersion: `enterprise-server@${enterpriseServerReleases.latest}`, currentPath: '/en/github/collaborating-with-issues-and-pull-requests/about-branches', currentLanguage: 'en' } @@ -96,14 +96,14 @@ describe('Page class', () => { expect(page.markdown.includes('(/articles/about-pull-requests)')).toBe(true) expect(page.markdown.includes('(/en/articles/about-pull-requests)')).toBe(false) expect($('a[href="/articles/about-pull-requests"]').length).toBe(0) - expect($(`a[href="/en/${nonEnterpriseDefaultVersion}/articles/about-pull-requests"]`).length).toBeGreaterThan(0) + expect($(`a[href="/en/${`enterprise-server@${enterpriseServerReleases.latest}`}/articles/about-pull-requests"]`).length).toBeGreaterThan(0) }) test('rewrites links on prerendered GraphQL page include the current language prefix and version', async () => { - const graphqlVersion = allVersions[nonEnterpriseDefaultVersion].miscVersionName + const graphqlVersion = allVersions[`enterprise-server@${enterpriseServerReleases.latest}`].miscVersionName const $ = cheerio.load(prerenderedObjects[graphqlVersion].html) expect($('a[href^="/graphql/reference/input-objects"]').length).toBe(0) - expect($(`a[href^="/en/${nonEnterpriseDefaultVersion}/graphql/reference/input-objects"]`).length).toBeGreaterThan(0) + expect($(`a[href^="/en/enterprise-server@${enterpriseServerReleases.latest}/graphql/reference/input-objects"]`).length).toBeGreaterThan(0) }) test('rewrites links in the intro to include the current language prefix and version', async () => { @@ -118,7 +118,7 @@ describe('Page class', () => { await page.render(context) const $ = cheerio.load(page.intro) expect($('a[href="/articles/about-pull-requests"]').length).toBe(0) - expect($(`a[href="/en/${nonEnterpriseDefaultVersion}/articles/about-pull-requests"]`).length).toBeGreaterThan(0) + expect($(`a[href="/en/articles/about-pull-requests"]`).length).toBeGreaterThan(0) }) test('does not rewrite links that include deprecated enterprise release numbers', async () => { @@ -235,7 +235,7 @@ describe('Page class', () => { test('sets versioned values', async () => { const page = await Page.init(opts) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/${nonEnterpriseDefaultVersion}/github/collaborating-with-issues-and-pull-requests/about-branches`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/github/collaborating-with-issues-and-pull-requests/about-branches`) expect(page.permalinks.find(permalink => permalink.pageVersion === `enterprise-server@${enterpriseServerReleases.oldestSupported}`).href).toBe(`/en/enterprise-server@${enterpriseServerReleases.oldestSupported}/github/collaborating-with-issues-and-pull-requests/about-branches`) }) @@ -245,9 +245,8 @@ describe('Page class', () => { basePath: path.join(__dirname, '../../content'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/${nonEnterpriseDefaultVersion}`) + expect(page.permalinks.find(permalink => permalink.pageVersion === 'homepage').href).toBe(`/en`) expect(page.permalinks.find(permalink => permalink.pageVersion === `enterprise-server@${enterpriseServerReleases.oldestSupported}`).href).toBe(`/en/enterprise-server@${enterpriseServerReleases.oldestSupported}`) - expect(page.permalinks.find(permalink => permalink.pageVersion === 'homepage').href).toBe('/en') }) test('permalinks for dotcom-only pages', async () => { @@ -256,7 +255,7 @@ describe('Page class', () => { basePath: path.join(__dirname, '../../content'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/${nonEnterpriseDefaultVersion}/github/getting-started-with-github/signing-up-for-a-new-github-account`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/github/getting-started-with-github/signing-up-for-a-new-github-account`) expect(page.permalinks.length).toBe(1) }) @@ -278,7 +277,7 @@ describe('Page class', () => { basePath: path.join(__dirname, '../fixtures'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/${nonEnterpriseDefaultVersion}/products/actions/some-category/some-article`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/products/actions/some-category/some-article`) expect(page.permalinks.length).toBe(1) }) diff --git a/tests/unit/permalink.js b/tests/unit/permalink.js index ba07c5f614..884b35f349 100644 --- a/tests/unit/permalink.js +++ b/tests/unit/permalink.js @@ -20,8 +20,8 @@ describe('Permalink class', () => { test('derives info for non-enterprise versioned homepage', () => { const permalink = new Permalink('en', nonEnterpriseDefaultVersion, 'index.md', 'Hello World') - expect(permalink.pageVersionTitle).toBe('Free, Pro, and Team') - expect(permalink.href).toBe(`/en/${nonEnterpriseDefaultVersion}`) + expect(permalink.pageVersionTitle).toBe('GitHub.com') + expect(permalink.href).toBe(`/en`) }) test('derives info for enterprise server versioned homepage', () => { @@ -32,8 +32,8 @@ describe('Permalink class', () => { test('derives info for GitHub.com homepage', () => { const permalink = new Permalink('en', nonEnterpriseDefaultVersion, 'github/index.md', 'Hello World') - expect(permalink.pageVersionTitle).toBe('Free, Pro, and Team') - expect(permalink.href).toBe(`/en/${nonEnterpriseDefaultVersion}/github`) + expect(permalink.pageVersionTitle).toBe('GitHub.com') + expect(permalink.href).toBe(`/en/github`) }) test('derives info for enterprise version of GitHub.com homepage', () => { diff --git a/tests/unit/versions.js b/tests/unit/versions.js index 1f3c8d2af7..b40dcb5a74 100644 --- a/tests/unit/versions.js +++ b/tests/unit/versions.js @@ -33,7 +33,7 @@ describe('versions middleware', () => { expect(currentVersion).toBe('homepage') currentVersion = await getJSON(`/en/${nonEnterpriseDefaultVersion}?json=currentVersion`) - expect(currentVersion).toBe(nonEnterpriseDefaultVersion) + expect(currentVersion).toBe('homepage') currentVersion = await getJSON(`/en/enterprise-server@${latest}?json=currentVersion`) expect(currentVersion).toBe(`enterprise-server@${latest}`) From 9809627129207ef8155b34a26060e43471559ba8 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 14 Jan 2021 17:10:12 -0500 Subject: [PATCH 31/65] lint --- tests/content/featured-links.js | 7 +++-- tests/content/site-tree.js | 6 ++--- tests/rendering/breadcrumbs.js | 31 +++++++++++------------ tests/rendering/header.js | 11 ++++---- tests/rendering/server.js | 29 ++++++++++----------- tests/rendering/sidebar.js | 3 +-- tests/routing/developer-site-redirects.js | 17 ++++++------- tests/routing/redirects.js | 8 +++--- tests/unit/liquid-helpers.js | 4 +-- tests/unit/page.js | 10 ++++---- tests/unit/permalink.js | 4 +-- 11 files changed, 62 insertions(+), 68 deletions(-) diff --git a/tests/content/featured-links.js b/tests/content/featured-links.js index 45d41b9190..b807fcee18 100644 --- a/tests/content/featured-links.js +++ b/tests/content/featured-links.js @@ -1,7 +1,6 @@ const { getDOM, getJSON } = require('../helpers/supertest') const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const japaneseCharacters = require('japanese-characters') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') describe('featuredLinks', () => { jest.setTimeout(3 * 60 * 1000) @@ -16,11 +15,11 @@ describe('featuredLinks', () => { const $ = await getDOM('/en') const $featuredLinks = $('.featured-links a') expect($featuredLinks).toHaveLength(9) - expect($featuredLinks.eq(0).attr('href')).toBe(`/en/github/getting-started-with-github/set-up-git`) + expect($featuredLinks.eq(0).attr('href')).toBe('/en/github/getting-started-with-github/set-up-git') expect($featuredLinks.eq(0).children('h4').text().startsWith('Set up Git')).toBe(true) expect($featuredLinks.eq(0).children('p').text().startsWith('At the heart of GitHub')).toBe(true) - expect($featuredLinks.eq(8).attr('href')).toBe(`/en/github/working-with-github-pages`) + expect($featuredLinks.eq(8).attr('href')).toBe('/en/github/working-with-github-pages') expect($featuredLinks.eq(8).children('h4').text().startsWith('GitHub Pages')).toBe(true) expect($featuredLinks.eq(8).children('p').text().startsWith('You can create a website')).toBe(true) }) @@ -58,7 +57,7 @@ describe('featuredLinks', () => { test('returns modified array of links', async () => { const gettingStartedLinks = await getJSON('/en?json=featuredLinks.gettingStarted') const expectedFirstLink = { - href: `/en/github/getting-started-with-github/set-up-git`, + href: '/en/github/getting-started-with-github/set-up-git', title: 'Set up Git' } expect(gettingStartedLinks[0].href).toEqual(expectedFirstLink.href) diff --git a/tests/content/site-tree.js b/tests/content/site-tree.js index 74ccdf6d70..f8becd21f3 100644 --- a/tests/content/site-tree.js +++ b/tests/content/site-tree.js @@ -24,14 +24,14 @@ describe('siteTree', () => { test('object order', () => { expect(Object.keys(siteTree)[0]).toBe('en') expect(Object.keys(siteTree.en)[0]).toBe(nonEnterpriseDefaultVersion) - expect(Object.keys(siteTree.en[nonEnterpriseDefaultVersion].products.github.categories)[0]).toBe(`/en/github/getting-started-with-github`) + expect(Object.keys(siteTree.en[nonEnterpriseDefaultVersion].products.github.categories)[0]).toBe('/en/github/getting-started-with-github') }) test('object structure', () => { expect(nonEnterpriseDefaultVersion in siteTree.en).toBe(true) expect(`enterprise-server@${latestEnterpriseRelease}` in siteTree.en).toBe(true) - expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.href`]).toBe(`/en/github`) - expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/github/getting-started-with-github.href`]).toBe(`/en/github/getting-started-with-github`) + expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.href`]).toBe('/en/github') + expect(flatTree[`en.${nonEnterpriseDefaultVersion}.products.github.categories./en/github/getting-started-with-github.href`]).toBe('/en/github/getting-started-with-github') }) describe('localized titles', () => { diff --git a/tests/rendering/breadcrumbs.js b/tests/rendering/breadcrumbs.js index 0675412077..81f4249207 100644 --- a/tests/rendering/breadcrumbs.js +++ b/tests/rendering/breadcrumbs.js @@ -1,5 +1,4 @@ const { getDOM, getJSON } = require('../helpers/supertest') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') const describeInternalOnly = process.env.GITHUB_REPOSITORY === 'github/docs-internal' ? describe : describe.skip @@ -52,13 +51,13 @@ describe('breadcrumbs', () => { test('English breadcrumbs link to English pages', async () => { const $ = await getDOM('/en/github/getting-started-with-github') const $breadcrumbs = $('.breadcrumbs a') - expect($breadcrumbs.eq(0).attr('href')).toBe(`/en/github`) + expect($breadcrumbs.eq(0).attr('href')).toBe('/en/github') }) test('localized breadcrumbs link to localize pages', async () => { const $ = await getDOM('/ja/github/getting-started-with-github') const $breadcrumbs = $('.breadcrumbs a') - expect($breadcrumbs.eq(0).attr('href')).toBe(`/ja/github`) + expect($breadcrumbs.eq(0).attr('href')).toBe('/ja/github') }) }) @@ -88,7 +87,7 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github?json=breadcrumbs') const expected = { product: { - href: `/en/github`, + href: '/en/github', title: 'GitHub.com' } } @@ -99,11 +98,11 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github?json=breadcrumbs') const expected = { product: { - href: `/en/github`, + href: '/en/github', title: 'GitHub.com' }, category: { - href: `/en/github/authenticating-to-github`, + href: '/en/github/authenticating-to-github', title: 'Authentication' } } @@ -114,15 +113,15 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github/keeping-your-account-and-data-secure?json=breadcrumbs') const expected = { product: { - href: `/en/github`, + href: '/en/github', title: 'GitHub.com' }, category: { - href: `/en/github/authenticating-to-github`, + href: '/en/github/authenticating-to-github', title: 'Authentication' }, maptopic: { - href: `/en/github/authenticating-to-github/keeping-your-account-and-data-secure`, + href: '/en/github/authenticating-to-github/keeping-your-account-and-data-secure', title: 'Keeping your account and data secure' } } @@ -133,19 +132,19 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/en/github/authenticating-to-github/creating-a-strong-password?json=breadcrumbs') const expected = { product: { - href: `/en/github`, + href: '/en/github', title: 'GitHub.com' }, category: { - href: `/en/github/authenticating-to-github`, + href: '/en/github/authenticating-to-github', title: 'Authentication' }, maptopic: { - href: `/en/github/authenticating-to-github/keeping-your-account-and-data-secure`, + href: '/en/github/authenticating-to-github/keeping-your-account-and-data-secure', title: 'Keeping your account and data secure' }, article: { - href: `/en/github/authenticating-to-github/creating-a-strong-password`, + href: '/en/github/authenticating-to-github/creating-a-strong-password', title: 'Creating a strong password' } } @@ -156,15 +155,15 @@ describe('breadcrumbs', () => { const breadcrumbs = await getJSON('/github/site-policy/github-privacy-statement?json=breadcrumbs') const expected = { product: { - href: `/en/github`, + href: '/en/github', title: 'GitHub.com' }, category: { - href: `/en/github/site-policy`, + href: '/en/github/site-policy', title: 'Site policy' }, article: { - href: `/en/github/site-policy/github-privacy-statement`, + href: '/en/github/site-policy/github-privacy-statement', title: 'GitHub Privacy Statement' } } diff --git a/tests/rendering/header.js b/tests/rendering/header.js index 8460c5d960..f9023235a6 100644 --- a/tests/rendering/header.js +++ b/tests/rendering/header.js @@ -1,6 +1,5 @@ const { getDOM } = require('../helpers/supertest') const { oldestSupported, latest } = require('../../lib/enterprise-server-releases') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') describe('header', () => { jest.setTimeout(5 * 60 * 1000) @@ -22,7 +21,7 @@ describe('header', () => { describe('language links', () => { test('lead to the same page in a different language', async () => { const $ = await getDOM('/en/github/administering-a-repository/enabling-required-status-checks') - expect($(`#languages-selector a[href="/ja/github/administering-a-repository/enabling-required-status-checks"]`).length).toBe(1) + expect($('#languages-selector a[href="/ja/github/administering-a-repository/enabling-required-status-checks"]').length).toBe(1) }) test('display the native name and the English name for each translated language', async () => { @@ -68,7 +67,7 @@ describe('header', () => { test('include github and admin, and emphasize the current product', async () => { const $ = await getDOM('/en/articles/enabling-required-status-checks') - const github = $(`#homepages a.active[href="/en/github"]`) + const github = $('#homepages a.active[href="/en/github"]') expect(github.length).toBe(1) expect(github.text().trim()).toBe('GitHub.com') expect(github.attr('class').includes('active')).toBe(true) @@ -82,15 +81,15 @@ describe('header', () => { test('point to homepages in the current page\'s language', async () => { const $ = await getDOM('/ja/articles/enabling-required-status-checks') - expect($(`#homepages a.active[href="/ja/github"]`).length).toBe(1) + expect($('#homepages a.active[href="/ja/github"]').length).toBe(1) expect($(`#homepages a[href="/ja/enterprise-server@${latest}/admin"]`).length).toBe(1) }) test('emphasizes the product that corresponds to the current page', async () => { const $ = await getDOM(`/en/enterprise/${oldestSupported}/user/github/setting-up-and-managing-your-github-user-account/setting-your-commit-email-address`) expect($(`#homepages a.active[href="/en/enterprise-server@${latest}/admin"]`).length).toBe(0) - expect($(`#homepages a[href="/en/github"]`).length).toBe(1) - expect($(`#homepages a.active[href="/en/github"]`).length).toBe(1) + expect($('#homepages a[href="/en/github"]').length).toBe(1) + expect($('#homepages a.active[href="/en/github"]').length).toBe(1) }) }) }) diff --git a/tests/rendering/server.js b/tests/rendering/server.js index 2ceec26816..edb868218e 100644 --- a/tests/rendering/server.js +++ b/tests/rendering/server.js @@ -3,7 +3,6 @@ const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const { get, getDOM, head } = require('../helpers/supertest') const { describeViaActionsOnly } = require('../helpers/conditional-runs') const path = require('path') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') const { loadPages } = require('../../lib/pages') describe('server', () => { @@ -214,7 +213,7 @@ describe('server', () => { test('displays links to categories on product TOCs', async () => { const $ = await getDOM('/en/github') - expect($(`article a[href="/en/github/getting-started-with-github"]`)).toHaveLength(1) + expect($('article a[href="/en/github/getting-started-with-github"]')).toHaveLength(1) }) describe('autogenerated mini TOCs', () => { @@ -296,7 +295,7 @@ describe('server', () => { test('dotcom articles on dotcom have links that include "en"', async () => { const $ = await getDOM('/en/articles/set-up-git') - expect($(`a[href="/en/articles/managing-files-on-github"]`).length).toBe(1) + expect($('a[href="/en/articles/managing-files-on-github"]').length).toBe(1) }) test('dotcom articles on dotcom have Enterprise Admin links with latest GHE version', async () => { @@ -316,12 +315,12 @@ describe('server', () => { test('dotcom-only links on GHE are dotcom-only', async () => { const $ = await getDOM(`${latestEnterprisePath}/github/setting-up-and-managing-your-github-profile/sending-your-github-enterprise-server-contributions-to-your-githubcom-profile`) - expect($(`article a[href="/en/articles/github-privacy-statement"]`).length).toBe(1) + expect($('article a[href="/en/articles/github-privacy-statement"]').length).toBe(1) }) test('desktop links on GHE are dotcom-only', async () => { const $ = await getDOM(`${latestEnterprisePath}/github/getting-started-with-github/set-up-git`) - expect($(`article a[href="/en/desktop/installing-and-configuring-github-desktop"]`).length).toBe(1) + expect($('article a[href="/en/desktop/installing-and-configuring-github-desktop"]').length).toBe(1) }) test('admin articles that link to non-admin articles have Enterprise user links', async () => { @@ -405,7 +404,7 @@ describe('server', () => { test('redirects old articles to their slugified URL', async () => { const res = await get('/articles/about-github-s-ip-addresses') - expect(res.text).toBe(`Moved Permanently. Redirecting to /en/github/authenticating-to-github/about-githubs-ip-addresses`) + expect(res.text).toBe('Moved Permanently. Redirecting to /en/github/authenticating-to-github/about-githubs-ip-addresses') }) test('redirects / to /en', async () => { @@ -444,13 +443,13 @@ describe('server', () => { describe('categories and map topics', () => { test('adds links to categories on the dotcom homepage', async () => { const $ = await getDOM('/en/github') - expect($(`article a[href="/en/github/managing-large-files"]`).length).toBe(1) + expect($('article a[href="/en/github/managing-large-files"]').length).toBe(1) expect($('article a[href="#managing-large-files"]').length).toBe(0) }) test('adds links to map topics on a category homepage', async () => { const $ = await getDOM('/en/github/setting-up-and-managing-your-github-user-account') - expect($(`article a[href="/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings"]`).length).toBe(1) + expect($('article a[href="/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings"]').length).toBe(1) expect($('article a[href="#managing-user-account-settings"]').length).toBe(0) }) @@ -461,7 +460,7 @@ describe('server', () => { test('map topic renders with h2 links to articles', async () => { const $ = await getDOM('/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings') - expect($(`a[href="/en/github/setting-up-and-managing-your-github-user-account/changing-your-github-username"] h2`).length).toBe(1) + expect($('a[href="/en/github/setting-up-and-managing-your-github-user-account/changing-your-github-username"] h2').length).toBe(1) }) test('map topic renders with one intro for every h2', async () => { @@ -572,26 +571,26 @@ describe('GitHub Enterprise URLs', () => { describe('GitHub Desktop URLs', () => { test('renders the GitHub Desktop homepage with correct links', async () => { const $ = await getDOM('/en/desktop') - expect($(`article a[href^="/en/desktop/"]`).length).toBeGreaterThan(1) + expect($('article a[href^="/en/desktop/"]').length).toBeGreaterThan(1) }) test('renders a Desktop category with expected links', async () => { const $ = await getDOM('/en/desktop/installing-and-configuring-github-desktop') - expect($(`article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) + expect($('article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]').length).toBeGreaterThan(1) }) test('renders a Desktop map topic', async () => { const $ = await getDOM('/en/desktop/installing-and-configuring-github-desktop/installing-and-authenticating-to-github-desktop') - expect($(`article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]`).length).toBeGreaterThan(1) + expect($('article a[href^="/en/desktop/installing-and-configuring-github-desktop/"]').length).toBeGreaterThan(1) }) test('renders a Desktop article within a map topic', async () => { - const res = await get(`/en/desktop/installing-and-configuring-github-desktop/installing-github-desktop`) + const res = await get('/en/desktop/installing-and-configuring-github-desktop/installing-github-desktop') expect(res.statusCode).toBe(200) }) test('renders the Desktop homepage in Japanese', async () => { - const res = await get(`/ja/desktop`) + const res = await get('/ja/desktop') expect(res.statusCode).toBe(200) }) }) @@ -743,7 +742,7 @@ describe('static routes', () => { }) describe('index pages', () => { - const nonEnterpriseOnlyPath = `/en/github/getting-started-with-github/verifying-your-email-address` + const nonEnterpriseOnlyPath = '/en/github/getting-started-with-github/verifying-your-email-address' test('includes dotcom-only links in dotcom TOC', async () => { const $ = await getDOM('/en/github/getting-started-with-github') diff --git a/tests/rendering/sidebar.js b/tests/rendering/sidebar.js index 5fbe8493cb..7376685666 100644 --- a/tests/rendering/sidebar.js +++ b/tests/rendering/sidebar.js @@ -1,5 +1,4 @@ const { getDOM } = require('../helpers/supertest') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') describe('sidebar', () => { jest.setTimeout(3 * 60 * 1000) @@ -31,7 +30,7 @@ describe('sidebar', () => { }) test('adds an `is-current-page` class to the sidebar link to the current page', async () => { - const url = `/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings` + const url = '/en/github/setting-up-and-managing-your-github-user-account/managing-user-account-settings' const $ = await getDOM(url) expect($('.sidebar .is-current-page').length).toBe(1) expect($('.sidebar .is-current-page a').attr('href')).toContain(url) diff --git a/tests/routing/developer-site-redirects.js b/tests/routing/developer-site-redirects.js index 5560d97601..9cf4673d00 100644 --- a/tests/routing/developer-site-redirects.js +++ b/tests/routing/developer-site-redirects.js @@ -2,7 +2,6 @@ const path = require('path') const { eachOfLimit } = require('async') const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const { get } = require('../helpers/supertest') -const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') const restRedirectFixtures = require('../fixtures/rest-redirects') const graphqlRedirectFixtures = require('../fixtures/graphql-redirects') const developerRedirectFixtures = require('../fixtures/developer-redirects') @@ -23,7 +22,7 @@ describe('developer redirects', () => { test('graphql homepage', async () => { const res = await get('/v4') expect(res.statusCode).toBe(301) - const expectedFinalPath = `/en/graphql` + const expectedFinalPath = '/en/graphql' expect(res.headers.location).toBe(expectedFinalPath) }) @@ -37,7 +36,7 @@ describe('developer redirects', () => { test('graphql overview paths', async () => { const oldPath = '/v4/breaking_changes' - const newPath = `/graphql/overview/breaking-changes` + const newPath = '/graphql/overview/breaking-changes' const res = await get(oldPath) expect(res.statusCode).toBe(301) expect(res.headers.location).toBe(`/en${newPath}`) @@ -52,12 +51,12 @@ describe('developer redirects', () => { test('graphql reference paths with child pages', async () => { const sclarRes = await get('/en/v4/scalar/boolean') expect(sclarRes.statusCode).toBe(301) - const sclarResFinalPath = `/en/graphql/reference/scalars#boolean` + const sclarResFinalPath = '/en/graphql/reference/scalars#boolean' expect(sclarRes.headers.location).toBe(sclarResFinalPath) const enumRes = await get('/en/v4/enum/searchtype') expect(enumRes.statusCode).toBe(301) - const enumResFinalPath = `/en/graphql/reference/enums#searchtype` + const enumResFinalPath = '/en/graphql/reference/enums#searchtype' expect(enumRes.headers.location).toBe(enumResFinalPath) }) }) @@ -66,21 +65,21 @@ describe('developer redirects', () => { let expectedFinalPath let res = await get('/v3') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/rest` + expectedFinalPath = '/en/rest' expect(res.headers.location).toBe(expectedFinalPath) // REST subresources like activity notifications don't have their own page // any more, so redirect to an anchor on the resource page res = await get('/en/v3/activity') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/rest/reference/activity` + expectedFinalPath = '/en/rest/reference/activity' expect(res.headers.location).toBe(expectedFinalPath) // REST subresources like activity notifications don't have their own page // any more, so redirect to an anchor on the resource page res = await get('/en/v3/activity/notifications') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/rest/reference/activity#notifications` + expectedFinalPath = '/en/rest/reference/activity#notifications' expect(res.headers.location).toBe(expectedFinalPath) // trailing slashes are handled separately by the `slashes` module; @@ -92,7 +91,7 @@ describe('developer redirects', () => { // non-reference redirects (e.g. guides) res = await get('/en/v3/guides/basics-of-authentication') expect(res.statusCode).toBe(301) - expectedFinalPath = `/en/rest/guides/basics-of-authentication` + expectedFinalPath = '/en/rest/guides/basics-of-authentication' expect(res.headers.location).toBe(expectedFinalPath) }) diff --git a/tests/routing/redirects.js b/tests/routing/redirects.js index a0185d6e66..90178cc663 100644 --- a/tests/routing/redirects.js +++ b/tests/routing/redirects.js @@ -36,7 +36,7 @@ describe('redirects', () => { page.buildRedirects() expect(page.redirects[`/en/${nonEnterpriseDefaultVersion}/github`]).toBe('/en/github') expect(page.redirects['/articles']).toBe('/en/github') - expect(page.redirects['/en/articles']).toBe(`/en/github`) + expect(page.redirects['/en/articles']).toBe('/en/github') expect(page.redirects[`/en/${nonEnterpriseDefaultVersion}/articles`]).toBe('/en/github') expect(page.redirects['/common-issues-and-questions']).toBe('/en/github') expect(page.redirects['/en/common-issues-and-questions']).toBe('/en/github') @@ -51,7 +51,7 @@ describe('redirects', () => { languageCode: 'en' }) page.buildRedirects() - const expected = `/en/github/collaborating-with-issues-and-pull-requests/about-conversations-on-github` + const expected = '/en/github/collaborating-with-issues-and-pull-requests/about-conversations-on-github' expect(page.redirects['/en/articles/about-discussions-in-issues-and-pull-requests']).toBe(expected) }) @@ -127,7 +127,7 @@ describe('redirects', () => { test('redirect_from for renamed pages', async () => { const { res } = await get('/ja/desktop/contributing-to-projects/changing-a-remote-s-url-from-github-desktop') expect(res.statusCode).toBe(301) - const expected = `/ja/desktop/contributing-and-collaborating-using-github-desktop/changing-a-remotes-url-from-github-desktop` + const expected = '/ja/desktop/contributing-and-collaborating-using-github-desktop/changing-a-remotes-url-from-github-desktop' expect(res.headers.location).toBe(expected) }) }) @@ -334,7 +334,7 @@ describe('redirects', () => { }) describe('desktop guide', () => { - const desktopGuide = `/en/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request` + const desktopGuide = '/en/desktop/contributing-and-collaborating-using-github-desktop/creating-an-issue-or-pull-request' const japaneseDesktopGuides = desktopGuide.replace('/en/', '/ja/') test('no language code redirects to english', async () => { diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index aeb7931d51..599eea1cbe 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -57,7 +57,7 @@ describe('liquid helper tags', () => { test('link_with_intro tag', async () => { const template = '{% link_with_intro /contributing-and-collaborating-using-github-desktop %}' - const page = pageMap[`/en/desktop/contributing-and-collaborating-using-github-desktop`] + const page = pageMap['/en/desktop/contributing-and-collaborating-using-github-desktop'] const expected = ` @@ -68,7 +68,7 @@ describe('liquid helper tags', () => { test('homepage_link_with_intro tag', async () => { const template = '{% homepage_link_with_intro /github/writing-on-github/basic-writing-and-formatting-syntax %}' - const page = pageMap[`/en/github/writing-on-github/basic-writing-and-formatting-syntax`] + const page = pageMap['/en/github/writing-on-github/basic-writing-and-formatting-syntax'] const expected = ` diff --git a/tests/unit/page.js b/tests/unit/page.js index fd01830f97..a2e10a3c6d 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -118,7 +118,7 @@ describe('Page class', () => { await page.render(context) const $ = cheerio.load(page.intro) expect($('a[href="/articles/about-pull-requests"]').length).toBe(0) - expect($(`a[href="/en/articles/about-pull-requests"]`).length).toBeGreaterThan(0) + expect($('a[href="/en/articles/about-pull-requests"]').length).toBeGreaterThan(0) }) test('does not rewrite links that include deprecated enterprise release numbers', async () => { @@ -235,7 +235,7 @@ describe('Page class', () => { test('sets versioned values', async () => { const page = await Page.init(opts) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/github/collaborating-with-issues-and-pull-requests/about-branches`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe('/en/github/collaborating-with-issues-and-pull-requests/about-branches') expect(page.permalinks.find(permalink => permalink.pageVersion === `enterprise-server@${enterpriseServerReleases.oldestSupported}`).href).toBe(`/en/enterprise-server@${enterpriseServerReleases.oldestSupported}/github/collaborating-with-issues-and-pull-requests/about-branches`) }) @@ -245,7 +245,7 @@ describe('Page class', () => { basePath: path.join(__dirname, '../../content'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === 'homepage').href).toBe(`/en`) + expect(page.permalinks.find(permalink => permalink.pageVersion === 'homepage').href).toBe('/en') expect(page.permalinks.find(permalink => permalink.pageVersion === `enterprise-server@${enterpriseServerReleases.oldestSupported}`).href).toBe(`/en/enterprise-server@${enterpriseServerReleases.oldestSupported}`) }) @@ -255,7 +255,7 @@ describe('Page class', () => { basePath: path.join(__dirname, '../../content'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/github/getting-started-with-github/signing-up-for-a-new-github-account`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe('/en/github/getting-started-with-github/signing-up-for-a-new-github-account') expect(page.permalinks.length).toBe(1) }) @@ -277,7 +277,7 @@ describe('Page class', () => { basePath: path.join(__dirname, '../fixtures'), languageCode: 'en' }) - expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe(`/en/products/actions/some-category/some-article`) + expect(page.permalinks.find(permalink => permalink.pageVersion === nonEnterpriseDefaultVersion).href).toBe('/en/products/actions/some-category/some-article') expect(page.permalinks.length).toBe(1) }) diff --git a/tests/unit/permalink.js b/tests/unit/permalink.js index 884b35f349..73d7b16324 100644 --- a/tests/unit/permalink.js +++ b/tests/unit/permalink.js @@ -21,7 +21,7 @@ describe('Permalink class', () => { test('derives info for non-enterprise versioned homepage', () => { const permalink = new Permalink('en', nonEnterpriseDefaultVersion, 'index.md', 'Hello World') expect(permalink.pageVersionTitle).toBe('GitHub.com') - expect(permalink.href).toBe(`/en`) + expect(permalink.href).toBe('/en') }) test('derives info for enterprise server versioned homepage', () => { @@ -33,7 +33,7 @@ describe('Permalink class', () => { test('derives info for GitHub.com homepage', () => { const permalink = new Permalink('en', nonEnterpriseDefaultVersion, 'github/index.md', 'Hello World') expect(permalink.pageVersionTitle).toBe('GitHub.com') - expect(permalink.href).toBe(`/en/github`) + expect(permalink.href).toBe('/en/github') }) test('derives info for enterprise version of GitHub.com homepage', () => { From 5cb989602ba9223f21f18856edaa670beb376927 Mon Sep 17 00:00:00 2001 From: mchammer01 <42146119+mchammer01@users.noreply.github.com> Date: Fri, 15 Jan 2021 09:04:17 +0000 Subject: [PATCH 32/65] add new section --- .../developers/overview/secret-scanning.md | 70 +++++++++++++++---- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/content/developers/overview/secret-scanning.md b/content/developers/overview/secret-scanning.md index 054637e2a5..44a6a8a924 100644 --- a/content/developers/overview/secret-scanning.md +++ b/content/developers/overview/secret-scanning.md @@ -1,6 +1,7 @@ --- title: Secret scanning intro: 'As a service provider, you can partner with {% data variables.product.prodname_dotcom %} to have your secret token formats secured through secret scanning, which searches for accidental commits of your secret format and can be sent to a service provider''s verify endpoint.' +miniTocMaxHeadingLevel: 4 redirect_from: - /partnerships/token-scanning/ - /partnerships/secret-scanning @@ -8,46 +9,46 @@ versions: free-pro-team: '*' --- - -{% data variables.product.prodname_dotcom %} scans repositories for known secret formats to prevent fraudulent use of credentials that were committed accidentally. Secret scanning happens by default on public repositories, and can be enabled on private repositories by repository administrators or organization owners. As a service provider, you can partner with {% data variables.product.prodname_dotcom %} so that your secret formats are included in our secret scanning. +{% data variables.product.prodname_dotcom %} scans repositories for known secret formats to prevent fraudulent use of credentials that were committed accidentally. {% data variables.product.prodname_secret_scanning_caps %} happens by default on public repositories, and can be enabled on private repositories by repository administrators or organization owners. As a service provider, you can partner with {% data variables.product.prodname_dotcom %} so that your secret formats are included in our {% data variables.product.prodname_secret_scanning %}. When a match of your secret format is found in a public repository, a payload is sent to an HTTP endpoint of your choice. -When a match of your secret format is found in a private repository configured for secret scanning, then repository admins are alerted and can view and manage the secret scanning results on {% data variables.product.prodname_dotcom %}. For more information, see "[Managing alerts from secret scanning](/github/administering-a-repository/managing-alerts-from-secret-scanning)". +When a match of your secret format is found in a private repository configured for {% data variables.product.prodname_secret_scanning %}, then repository admins are alerted and can view and manage the {% data variables.product.prodname_secret_scanning %} results on {% data variables.product.prodname_dotcom %}. For more information, see "[Managing alerts from {% data variables.product.prodname_secret_scanning %}](/github/administering-a-repository/managing-alerts-from-secret-scanning)". {% note %} -**Note:** Secret scanning for private repositories is currently in beta. +**Note:** {% data variables.product.prodname_secret_scanning_caps %} for private repositories is currently in beta. {% endnote %} -This article describes how you can partner with {% data variables.product.prodname_dotcom %} as a service provider and join the secret scanning program. +This article describes how you can partner with {% data variables.product.prodname_dotcom %} as a service provider and join the {% data variables.product.prodname_secret_scanning %} program. -### The secret scanning process +### The {% data variables.product.prodname_secret_scanning %} process -##### How secret scanning works in a public repository +##### How {% data variables.product.prodname_secret_scanning %} works in a public repository -The following diagram summarizes the secret scanning process for public repositories, with any matches sent to a service provider's verify endpoint. +The following diagram summarizes the {% data variables.product.prodname_secret_scanning %} process for public repositories, with any matches sent to a service provider's verify endpoint. -![Flow diagram showing the process of scanning for a secret and sending matches to a service provider's verify endpoint](/assets/images/secret-scanning-flow.png "Secret scanning flow") +![Flow diagram showing the process of scanning for a secret and sending matches to a service provider's verify endpoint](/assets/images/secret-scanning-flow.png "{% data variables.product.prodname_secret_scanning_caps %} flow") -### Joining the secret scanning program on {% data variables.product.prodname_dotcom %} +### Joining the {% data variables.product.prodname_secret_scanning %} program on {% data variables.product.prodname_dotcom %} 1. Contact {% data variables.product.prodname_dotcom %} to get the process started. 1. Identify the relevant secrets you want to scan for and create regular expressions to capture them. -1. For secret matches found in public repositories, create a secret alert service which accepts webhooks from {% data variables.product.prodname_dotcom %} that contain the secret scanning message payload. +1. For secret matches found in public repositories, create a secret alert service which accepts webhooks from {% data variables.product.prodname_dotcom %} that contain the {% data variables.product.prodname_secret_scanning %} message payload. 1. Implement signature verification in your secret alert service. 1. Implement secret revocation and user notification in your secret alert service. +1. Provide feedback for false positives (optional). #### Contact {% data variables.product.prodname_dotcom %} to get the process started To get the enrollment process started, email secret-scanning@github.com. -You will receive details on the secret scanning program, and you will need to agree to {% data variables.product.prodname_dotcom %}'s terms of participation before proceeding. +You will receive details on the {% data variables.product.prodname_secret_scanning %} program, and you will need to agree to {% data variables.product.prodname_dotcom %}'s terms of participation before proceeding. #### Identify your secrets and create regular expressions -To scan for your secrets, {% data variables.product.prodname_dotcom %} needs the following pieces of information for each secret that you want included in the secret scanning program: +To scan for your secrets, {% data variables.product.prodname_dotcom %} needs the following pieces of information for each secret that you want included in the {% data variables.product.prodname_secret_scanning %} program: * A unique, human readable name for the secret type. We'll use this to generate the `Type` value in the message payload later. * A regular expression which finds the secret type. Be as precise as possible, because this will reduce the number of false positives. @@ -279,4 +280,45 @@ puts openssl_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(signature), #### Implement secret revocation and user notification in your secret alert service -For secret scanning in public repositories, you can enhance your secret alert service to revoke the exposed secrets and notify the affected users. How you implement this in your secret alert service is up to you, but we recommend considering any secrets that {% data variables.product.prodname_dotcom %} sends you messages about as public and compromised. +For {% data variables.product.prodname_secret_scanning %} in public repositories, you can enhance your secret alert service to revoke the exposed secrets and notify the affected users. How you implement this in your secret alert service is up to you, but we recommend considering any secrets that {% data variables.product.prodname_dotcom %} sends you messages about as public and compromised. + +#### Provide feedback for false positives + +We collect feedback on the validity of the detected individual secrets in partner responses. Email us at secret-scanning@github.com if you wish to to take part, and get feedback collection enabled. + +When we report secrets to you, we send a JSON array with each element containing the token, type identifier, and commit URL. When you send us feedback, you send us information about whether the detected token was a real or false credential. + +You can find below the two response formats that we support in terms of feedback: + +``` +[ + { + "token_raw": "The raw token", + "token_type": "ACompany_API_token", + "label": "true_positive" + } +] +``` +You may also provide the token in hashed form after performing a one way cryptographic hash of the raw token using SHA-256: + +``` +[ + { + "token_hash": "The SHA 256 hashed form of the raw token", + "token_type": "ACompany_API_token", + "label": "false_positive" + } +] +``` +A few important points: +- You should only send us either the raw form of the token ("token_raw"), or the hashed form ("token_hash"), but not both. +- For the hashed form of the raw token, you can only use SHA-256 to hash the token, not any other hashing algorithm. +- The label indicates whether the token is a true ("true_positive") or a false positive ("false_positive"). Only these two lowercased literal strings are allowed. + +{% note %} + +**Note:** Our request timeout is set to be higher (that is, 30 seconds) for responding partners with false positives data. If you require a timeout larger than 30 seconds, email us at secret-scanning@github.com. + +{% endnote %} + + From 535dae5a8a57210332f686c17e8cf14c549e56d2 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 09:38:42 -0500 Subject: [PATCH 33/65] remove no-longer-needed feature flag --- feature-flags.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/feature-flags.json b/feature-flags.json index 64d7876891..64c69f19d7 100644 --- a/feature-flags.json +++ b/feature-flags.json @@ -1,5 +1,4 @@ { "FEATURE_TEST_TRUE": true, - "FEATURE_TEST_FALSE": false, - "FEATURE_REMOVE_FPT": false + "FEATURE_TEST_FALSE": false } From b4690547a7af9b4e2f19873858c963f60439c5a0 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 09:42:29 -0500 Subject: [PATCH 34/65] remove no-longer-needed feature flag --- lib/all-versions.js | 2 +- lib/redirects/get-old-paths-from-permalink.js | 21 ++++++------------- middleware/breadcrumbs.js | 12 +---------- 3 files changed, 8 insertions(+), 27 deletions(-) diff --git a/lib/all-versions.js b/lib/all-versions.js index d7fee98899..6f0f6027de 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -10,7 +10,7 @@ const plans = [ { // free-pro-team is **not** a user-facing version and is stripped from URLs. // See lib/remove-fpt-from-path.js for details. plan: 'free-pro-team', - planTitle: process.env.FEATURE_REMOVE_FPT ? 'GitHub.com' : 'Free, Pro, and Team', + planTitle: 'Free, Pro, and Team', releases: [latestNonNumberedRelease], latestRelease: latestNonNumberedRelease, nonEnterpriseDefault: true, // permanent way to refer to this plan if the name changes diff --git a/lib/redirects/get-old-paths-from-permalink.js b/lib/redirects/get-old-paths-from-permalink.js index a8781a72fb..b0acb22000 100644 --- a/lib/redirects/get-old-paths-from-permalink.js +++ b/lib/redirects/get-old-paths-from-permalink.js @@ -57,22 +57,13 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren // ------ BEGIN MODERN VERSION FORMAT REPLACEMENTS ------// if (currentlySupportedVersions.includes(currentVersion) || versionSatisfiesRange(currentVersion, `>${lastReleaseWithLegacyFormat}`)) { (new Set(oldPaths)).forEach(oldPath => { - if (!process.env.FEATURE_REMOVE_FPT) { - // create old path /github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace(`/${nonEnterpriseDefaultVersion}`, '')) + // create old path /github from new path /free-pro-team@latest/github + oldPaths.add(oldPath + .replace(`/${nonEnterpriseDefaultVersion}`, '')) - // create old path /free-pro-team/github from new path /free-pro-team@latest/github - oldPaths.add(oldPath - .replace('@latest', '')) - } - - // TODO THIS ONE IS TRICKY BECAUSE OF VERSIONS TO ENABLE - // if (process.env.FEATURE_REMOVE_FPT) { - // // create old path /free-pro-team@latest/github from new path /github - // oldPaths.add(oldPath - // .replace(`/${nonEnterpriseDefaultVersion}`, '')) - // } + // create old path /free-pro-team/github from new path /free-pro-team@latest/github + oldPaths.add(oldPath + .replace('@latest', '')) // create old path /enterprise/ from new path /enterprise-server@ oldPaths.add(oldPath diff --git a/middleware/breadcrumbs.js b/middleware/breadcrumbs.js index bc77e0cfc8..88cb31b425 100644 --- a/middleware/breadcrumbs.js +++ b/middleware/breadcrumbs.js @@ -30,17 +30,7 @@ module.exports = async (req, res, next) => { } // drop the version segment so pathParts now starts with /product - if (!process.env.FEATURE_REMOVE_FPT) { - pathParts.shift() - } - - if (process.env.FEATURE_REMOVE_FPT) { - // if this is not FPT, drop the version segment so pathParts now starts with /product - // if this is FPT, there is no version segment so pathParts already starts with /product - if (req.context.currentVersion !== nonEnterpriseDefaultVersion) { - pathParts.shift() - } - } + pathParts.shift() if (!pathParts[1]) return next() From 16c3fd56e02f1dde9eaec1ae45bb2c09b5010768 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 09:50:23 -0500 Subject: [PATCH 35/65] go back to using path.join --- lib/all-products.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/all-products.js b/lib/all-products.js index e56ffc21b3..9795981941 100644 --- a/lib/all-products.js +++ b/lib/all-products.js @@ -47,7 +47,7 @@ sortedProductIds.forEach(productId => { const toc = slash(path.join(dir, 'index.md')) const { data } = frontmatter(fs.readFileSync(toc, 'utf8')) const applicableVersions = getApplicableVersions(data.versions, toc) - const href = removeFPTFromPath(`/${applicableVersions[0]}/${productId}`) + const href = removeFPTFromPath(slash(path.join('/', applicableVersions[0], productId))) internalProducts[productId] = { id: productId, From 3973df5ef20dab8551d0fbcec9c88a72e08e1872 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 09:56:40 -0500 Subject: [PATCH 36/65] lint --- middleware/breadcrumbs.js | 1 - 1 file changed, 1 deletion(-) diff --git a/middleware/breadcrumbs.js b/middleware/breadcrumbs.js index 88cb31b425..3069fab536 100644 --- a/middleware/breadcrumbs.js +++ b/middleware/breadcrumbs.js @@ -1,6 +1,5 @@ const path = require('path') const { getPathWithoutLanguage } = require('../lib/path-utils') -const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') module.exports = async (req, res, next) => { if (!req.context.page) return next() From 308e62616dbde0e450cf02633584cc1c991af20e Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 09:56:52 -0500 Subject: [PATCH 37/65] use path.join instead of string interpolation for consistency --- lib/all-products.js | 2 +- lib/all-versions.js | 3 +-- lib/redirects/get-docs-path-from-developer-path.js | 3 ++- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/all-products.js b/lib/all-products.js index e92bdf2d55..f65a8a11be 100644 --- a/lib/all-products.js +++ b/lib/all-products.js @@ -46,7 +46,7 @@ sortedProductIds.forEach(productId => { const toc = slash(path.join(dir, 'index.md')) const { data } = frontmatter(fs.readFileSync(toc, 'utf8')) const applicableVersions = getApplicableVersions(data.versions, toc) - const href = `/${applicableVersions[0]}/${productId}` + const href = slash(path.join('/', applicableVersions[0], productId)) internalProducts[productId] = { id: productId, diff --git a/lib/all-versions.js b/lib/all-versions.js index 6f0f6027de..8af27e1e3f 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -7,8 +7,7 @@ const versionDelimiter = '@' const latestNonNumberedRelease = 'latest' const plans = [ - { // free-pro-team is **not** a user-facing version and is stripped from URLs. - // See lib/remove-fpt-from-path.js for details. + { plan: 'free-pro-team', planTitle: 'Free, Pro, and Team', releases: [latestNonNumberedRelease], diff --git a/lib/redirects/get-docs-path-from-developer-path.js b/lib/redirects/get-docs-path-from-developer-path.js index c50c6e3b81..bf7f0a0b5d 100644 --- a/lib/redirects/get-docs-path-from-developer-path.js +++ b/lib/redirects/get-docs-path-from-developer-path.js @@ -1,3 +1,4 @@ +const path = require('path') const patterns = require('../patterns') const { latest } = require('../enterprise-server-releases') const { getPathWithoutLanguage, getPathWithoutVersion } = require('../path-utils') @@ -73,7 +74,7 @@ module.exports = function getDocsPathFromDeveloperPath (oldDeveloperPath, allRed // old developer routes that include 'enterprise-admin' should always redirect to enterprise server if (fragment && newPath.includes('/rest/reference/enterprise-admin') && !patterns.enterpriseServer.test(newPath)) { - newPath = `/en/enterprise-server@${latest}${getPathWithoutLanguage(getPathWithoutVersion(newPath))}` + newPath = path.join('/en', `enterprise-server@${latest}`, getPathWithoutLanguage(getPathWithoutVersion(newPath))) } // show an error if the page to be redirected to doesn't exist From 51da7a97495940a89b36d89427e8ec5020b2af92 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 10:11:17 -0500 Subject: [PATCH 38/65] few tweaks --- lib/redirects/permalinks.js | 1 + lib/site-tree.js | 5 ++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 82cdf9706e..4785fd3fe9 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -41,6 +41,7 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href + redirects[`/en${versionedFrontmatterOldPath}`] = permalink.href // then get an array of possible alternative old paths from the current versioned old path const possibleOldPathsForVersionedOldPaths = getOldPathsFromPermalink(versionedFrontmatterOldPath, permalink.languageCode, permalink.pageVersion) diff --git a/lib/site-tree.js b/lib/site-tree.js index 66c64ab2e1..736e51cc79 100644 --- a/lib/site-tree.js +++ b/lib/site-tree.js @@ -3,7 +3,7 @@ const products = Object.values(require('./all-products')) const languageCodes = Object.keys(require('./languages')) const addTitlesToTree = require('./site-tree-titles') const allVersions = Object.keys(require('./all-versions')) -const { getVersionStringFromPath } = require('./path-utils') +const { getPathWithoutVersion } = require('./path-utils') const getApplicableVersions = require('./get-applicable-versions') const findPage = require('./find-page') @@ -46,8 +46,7 @@ module.exports = async function buildSiteTree (pageMap, site, redirects) { if (!getApplicableVersions(page.versions).includes(version)) return // item.hrefs have a default version via lib/all-products, so update to the current version - const versionFromPath = getVersionStringFromPath(item.href) - const versionedProductHref = path.join('/', languageCode, item.href.replace(versionFromPath, version)) + const versionedProductHref = path.join('/', languageCode, version, getPathWithoutVersion(item.href)) product.categories = buildCategoriesTree(page.tocItems, versionedProductHref, pageMap, redirects, version) From 3ff1bfca5ace7aa12a04d3f1369f930864c77402 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 10:49:12 -0500 Subject: [PATCH 39/65] account for early access --- lib/path-utils.js | 10 +++++++--- middleware/early-access-breadcrumbs.js | 13 ++++++++++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/path-utils.js b/lib/path-utils.js index 6d75a185e3..989a24c308 100644 --- a/lib/path-utils.js +++ b/lib/path-utils.js @@ -76,9 +76,13 @@ function getProductStringFromPath (href) { if (href === '/') return 'homepage' - return allProducts[href.split('/')[2]] - ? href.split('/')[2] - : href.split('/')[1] + const pathParts = href.split('/') + + if (pathParts.includes('early-access')) return 'early-access' + + return allProducts[pathParts[2]] + ? pathParts[2] + : pathParts[1] } // Return the corresponding object for the product segment in a path diff --git a/middleware/early-access-breadcrumbs.js b/middleware/early-access-breadcrumbs.js index a04cfc1118..2b7c95ca76 100644 --- a/middleware/early-access-breadcrumbs.js +++ b/middleware/early-access-breadcrumbs.js @@ -1,5 +1,7 @@ const path = require('path') const { getPathWithoutLanguage } = require('../lib/path-utils') +const nonEnterpriseDefaultVersion = require('../lib/non-enterprise-default-version') +const removeFPTFromPath = require('../lib/remove-fpt-from-path') // Early Access content doesn't conform to the same structure as other products, so we // can't derive breadcrumbs from the siteTree in the same way. Hence, this separate middleware. @@ -22,8 +24,13 @@ module.exports = async (req, res, next) => { // drop first '/' pathParts.shift() - // drop the version and early-accesss segments so pathParts now starts with /product - pathParts.shift() + // if this is not FPT, drop the version segment + // if this is FPT, there is no version segment + if (req.context.currentVersion !== nonEnterpriseDefaultVersion) { + pathParts.shift() + } + + // drop the early-accesss segments so pathParts now starts with /product pathParts.shift() // Early Access products do not require an index.md, so look for a matching public product @@ -40,7 +47,7 @@ module.exports = async (req, res, next) => { // get Early Access category path // e.g., `enforcing-best-practices-with-github-policies` in /free-pro-team@latest/early-access/github/enforcing-best-practices-with-github-policies - const categoryPath = path.posix.join('/', 'en', req.context.currentVersion, 'early-access', pathParts[0], pathParts[1]) + const categoryPath = removeFPTFromPath(path.posix.join('/', 'en', req.context.currentVersion, 'early-access', pathParts[0], pathParts[1])) const category = req.context.pages[categoryPath] if (!category) return next() From 9ca9acd286ca5af6c3219d3bb36262e534d00848 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 10:53:44 -0500 Subject: [PATCH 40/65] add comment to FPT in all-versions --- lib/all-versions.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/all-versions.js b/lib/all-versions.js index 5ea9f3d1aa..64fe6c9c8d 100644 --- a/lib/all-versions.js +++ b/lib/all-versions.js @@ -7,7 +7,8 @@ const versionDelimiter = '@' const latestNonNumberedRelease = 'latest' const plans = [ - { + { // free-pro-team is **not** a user-facing version and is stripped from URLs. + // See lib/remove-fpt-from-path.js for details. plan: 'free-pro-team', planTitle: 'GitHub.com', releases: [latestNonNumberedRelease], From a8470e9034cf26fd976a6d9173f8480b5a649b3e Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 11:05:48 -0500 Subject: [PATCH 41/65] remove unnecessary redirect (cuts down on about 18k redirects) --- lib/redirects/permalinks.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/redirects/permalinks.js b/lib/redirects/permalinks.js index 4785fd3fe9..82cdf9706e 100644 --- a/lib/redirects/permalinks.js +++ b/lib/redirects/permalinks.js @@ -41,7 +41,6 @@ module.exports = function generateRedirectsForPermalinks (permalinks, redirectFr // add it to the redirects object redirects[versionedFrontmatterOldPath] = permalink.href - redirects[`/en${versionedFrontmatterOldPath}`] = permalink.href // then get an array of possible alternative old paths from the current versioned old path const possibleOldPathsForVersionedOldPaths = getOldPathsFromPermalink(versionedFrontmatterOldPath, permalink.languageCode, permalink.pageVersion) From 3bf432e656d7ee7b8220f3ad1f053f07b9bdc2c2 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 11:21:52 -0500 Subject: [PATCH 42/65] refactor --- middleware/contextualizers/early-access-links.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/middleware/contextualizers/early-access-links.js b/middleware/contextualizers/early-access-links.js index 056efe4586..f09c68f1d9 100644 --- a/middleware/contextualizers/early-access-links.js +++ b/middleware/contextualizers/early-access-links.js @@ -7,17 +7,14 @@ module.exports = function earlyAccessContext (req, res, next) { // Get a list of all hidden pages per version const earlyAccessPageLinks = uniq(Object.values(req.context.pages) - .filter(page => page.hidden) - // Do not include early access landing page - .filter(page => page.relativePath !== 'early-access/index.md') - // Create Markdown links - .map(page => { - return page.permalinks.map(permalink => `- [${permalink.title}](${permalink.href})`) - }) + .filter(page => page.hidden && page.relativePath.startsWith('early-access') && page.relativePath !== 'early-access/index.md') + .map(page => page.permalinks) .flat()) // Get links for the current version - .filter(link => link.includes(req.context.currentVersion)) + .filter(permalink => req.context.currentVersion === permalink.pageVersion) .sort() + // Create Markdown links + .map(permalink => `- [${permalink.title}](${permalink.href})`) // Add to the rendering context // This is only used in the separate EA repo on local development From 48cbff9ef83f9ee5f3709c52e125ba913e57b22a Mon Sep 17 00:00:00 2001 From: mchammer01 <42146119+mchammer01@users.noreply.github.com> Date: Fri, 15 Jan 2021 16:38:11 +0000 Subject: [PATCH 43/65] first stab --- ...y-permission-levels-for-an-organization.md | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md index 9dfe09780a..e8ba36def3 100644 --- a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md +++ b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md @@ -1,6 +1,7 @@ --- title: Repository permission levels for an organization intro: 'You can customize access to each repository in your organization with granular permission levels, giving people access to the features and tasks they need.' +miniTocMaxHeadingLevel: 4 redirect_from: - /articles/repository-permission-levels-for-an-organization-early-access-program/ - /articles/repository-permission-levels-for-an-organization @@ -43,6 +44,12 @@ In addition to managing organization-level settings, organization owners have ad ### Repository access for each permission level +{% note %} + +**Note:** Repository permissions required for security features are listed in [Permission levels for code security features](#permission-levels-for-code-security-features) below. + +{% endnote %} + | Repository action | Read | Triage | Write | Maintain | Admin | |:---|:---:|:---:|:---:|:---:|:---:| | Pull from the person or team's assigned repositories | **X** | **X** | **X** | **X** | **X** | @@ -104,17 +111,7 @@ In addition to managing organization-level settings, organization owners have ad | Rename the repository's default branch (see "[Renaming a branch](/github/administering-a-repository/renaming-a-branch)") | | | | | **X** | | Rename a branch other than the repository's default branch (see "[Renaming a branch](/github/administering-a-repository/renaming-a-branch)") | | | **X** | **X** | **X** |{% endif %} | Manage webhooks and deploy keys | | | | | **X** |{% if currentVersion == "free-pro-team@latest" %} -| [Enable the dependency graph](/github/visualizing-repository-data-with-graphs/exploring-the-dependencies-and-dependents-of-a-repository) for a private repository | | | | | **X** | -| Receive [{% data variables.product.prodname_dependabot_alerts %} for vulnerable dependencies](/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies) in a repository | | | | | **X** | -| [Dismiss {% data variables.product.prodname_dependabot_alerts %}](/github/managing-security-vulnerabilities/viewing-and-updating-vulnerable-dependencies-in-your-repository) | | | | | **X** | -| [Designate additional people or teams to receive {% data variables.product.prodname_dependabot_alerts %}](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts) for vulnerable dependencies | | | | | **X** | -| [Manage data use settings for your private repository](/github/understanding-how-github-uses-and-protects-your-data/managing-data-use-settings-for-your-private-repository) | | | | | **X** | -| Create [security advisories](/github/managing-security-vulnerabilities/about-github-security-advisories) | | | | | **X** | -| Manage access to {% data variables.product.prodname_GH_advanced_security %} features (see "[Managing security and analysis settings for your organization](/github/setting-up-and-managing-organizations-and-teams/managing-security-and-analysis-settings-for-your-organization)") | | | | | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} -| [View {% data variables.product.prodname_code_scanning %} alerts on pull requests](/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests) | **X** | **X** | **X** | **X** | **X** | -| [List, dismiss, and delete {% data variables.product.prodname_code_scanning %} alerts](/github/finding-security-vulnerabilities-and-errors-in-your-code/managing-code-scanning-alerts-for-your-repository) | | | **X** | **X** | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} -| [View {% data variables.product.prodname_secret_scanning %} alerts in a repository, and also resolve, revoke or re-open {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-alerts-from-secret-scanning) | | | | | **X** | -| [Designate additional people or teams to receive {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts) in repositories | | | | | **X** |{% endif %} +| [Manage data use settings for your private repository](/github/understanding-how-github-uses-and-protects-your-data/managing-data-use-settings-for-your-private-repository) | | | | | **X** |{% endif %} | [Manage the forking policy for a repository](/github/administering-a-repository/managing-the-forking-policy-for-your-repository) | | | | | **X** | | [Transfer repositories into the organization](/articles/restricting-repository-creation-in-your-organization) | | | | | **X** | | [Delete or transfer repositories out of the organization](/articles/setting-permissions-for-deleting-or-transferring-repositories) | | | | | **X** | @@ -132,6 +129,23 @@ In addition to managing organization-level settings, organization owners have ad | [Create new discussions and comment on existing discussions](/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion) | **X** | **X** | **X** | **X** | **X** | | [Delete a discussion](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository#deleting-a-discussion) | | | | **X** | **X** |{% endif %} +#### Permission levels for code security features + +| Repository action | Read | Triage | Write | Maintain | Admin | +|:---|:---:|:---:|:---:|:---:|:---:|{% if currentVersion == "free-pro-team@latest" %} +| Receive [{% data variables.product.prodname_dependabot_alerts %} for vulnerable dependencies](/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies) in a repository | | | | | **X** | +| [Dismiss {% data variables.product.prodname_dependabot_alerts %}](/github/managing-security-vulnerabilities/viewing-and-updating-vulnerable-dependencies-in-your-repository) | | | | | **X** | +| [Designate additional people or teams to receive {% data variables.product.prodname_dependabot_alerts %}](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts) for vulnerable dependencies | | | | | **X** | +| Create [security advisories](/github/managing-security-vulnerabilities/about-github-security-advisories) | | | | | **X** | +| Manage access to {% data variables.product.prodname_GH_advanced_security %} features (see "[Managing security and analysis settings for your organization](/github/setting-up-and-managing-organizations-and-teams/managing-security-and-analysis-settings-for-your-organization)") | | | | | **X** | +| [Enable the dependency graph](/github/visualizing-repository-data-with-graphs/exploring-the-dependencies-and-dependents-of-a-repository) for a private repository | | | | | **X** | +| [View dependency reviews](/github/collaborating-with-issues-and-pull-requests/reviewing-dependency-changes-in-a-pull-request) | **X** | **X** | **X** | **X** | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} +| [View {% data variables.product.prodname_code_scanning %} alerts on pull requests](/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests) | **X** | **X** | **X** | **X** | **X** | +| [List, dismiss, and delete {% data variables.product.prodname_code_scanning %} alerts](/github/finding-security-vulnerabilities-and-errors-in-your-code/managing-code-scanning-alerts-for-your-repository) | | | **X** | **X** | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} +| [View {% data variables.product.prodname_secret_scanning %} alerts in a repository, and also resolve, revoke or re-open {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-alerts-from-secret-scanning) | | | | | **X** | +| [Designate additional people or teams to receive {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts) in repositories | | | | | **X** |{% endif %} + + ### Further reading - "[Managing access to your organization's repositories](/articles/managing-access-to-your-organization-s-repositories)" From 77ee3137ef0f75f8ba007903af0b9ef446a4c09f Mon Sep 17 00:00:00 2001 From: Laura Coursen Date: Fri, 15 Jan 2021 10:43:14 -0600 Subject: [PATCH 44/65] Refactor protected branches content (#17277) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add new structure to index.md * Move all conceptual and troubleshooting content * Add more redirects * Update links * Reorganize "About" article * Tweak some conceptual content * Rename procedural article * Fix article title in index.md * Fix links * Add more redirects * Fix more links * Add redirects for "Managing..." and fix links * Consolidate procedural information * Remove duplicate redirect * Fix indentation * Add 💅 * Add header * Add editing and deleting * 💅 conceptual content * 💅 conceptual content * 💅 troubleshooting article * Clarify default behavior * 💅 gated feature clarification * Add 💅 * Add 💅 * update hardcoded links in tests * Fix gated feature reusable Co-Authored-By: Matt Pollard * Step out of the way while Matt improves all of the legacy content Co-authored-by: Matt Pollard * Tweak gated feature reusable Co-authored-by: Sarah Schneider Co-authored-by: Matt Pollard --- .../delete-branch-protection-rule.png | Bin 0 -> 9749 bytes .../edit-branch-protection-rule.png | Bin 0 -> 9842 bytes .../save-branch-protection-rule.png | Bin 0 -> 3051 bytes .../creating-ci-tests-with-the-checks-api.md | 2 +- .../about-branch-restrictions.md | 30 ---- .../about-merge-methods-on-github.md | 2 +- .../about-protected-branches.md | 131 ++++++++++++++++-- .../about-required-commit-signing.md | 29 ---- ...bout-required-reviews-for-pull-requests.md | 36 ----- .../about-required-status-checks.md | 72 ---------- .../configuring-protected-branches.md | 42 ------ .../enabling-branch-restrictions.md | 33 ----- ...enabling-deletion-of-a-protected-branch.md | 23 --- ...ling-force-pushes-to-a-protected-branch.md | 33 ----- .../enabling-required-commit-signing.md | 25 ---- ...ling-required-reviews-for-pull-requests.md | 38 ----- .../enabling-required-status-checks.md | 30 ---- .../administering-a-repository/index.md | 15 +- .../managing-a-branch-protection-rule.md | 100 +++++++++++++ .../requiring-a-linear-commit-history.md | 31 ----- .../troubleshooting-required-status-checks.md | 38 +++++ .../types-of-required-status-checks.md | 22 --- .../about-commit-signature-verification.md | 2 +- .../about-branches.md | 2 +- .../about-pull-request-reviews.md | 5 +- ...ng-a-pull-request-with-required-reviews.md | 5 +- ...pull-request-branch-created-from-a-fork.md | 2 +- .../dismissing-a-pull-request-review.md | 4 +- .../merging-a-pull-request.md | 2 +- ...wing-proposed-changes-in-a-pull-request.md | 2 +- .../about-code-owners.md | 2 +- ...g-code-scanning-alerts-in-pull-requests.md | 2 +- ...iltering-pull-requests-by-review-status.md | 2 +- ...arch-to-filter-issues-and-pull-requests.md | 2 +- .../gated-features/branch-restrictions.md | 3 - .../gated-features/protected-branches.md | 2 +- .../pull_requests/about-protected-branches.md | 1 - .../required-checks-must-pass-to-merge.md | 2 +- .../required-reviews-for-prs-summary.md | 4 +- .../repositories/branch-rules-example.md | 2 +- .../repositories/include-administrators.md | 2 - .../protected-branches-options.md | 1 - .../repositories/required-status-merge-tip.md | 5 - .../review-policy-overlapping-commits.md | 2 +- ...quash-and-rebase-linear-commit-hisitory.md | 2 +- tests/rendering/header.js | 6 +- 46 files changed, 282 insertions(+), 514 deletions(-) create mode 100644 assets/images/help/repository/delete-branch-protection-rule.png create mode 100644 assets/images/help/repository/edit-branch-protection-rule.png create mode 100644 assets/images/help/repository/save-branch-protection-rule.png delete mode 100644 content/github/administering-a-repository/about-branch-restrictions.md delete mode 100644 content/github/administering-a-repository/about-required-commit-signing.md delete mode 100644 content/github/administering-a-repository/about-required-reviews-for-pull-requests.md delete mode 100644 content/github/administering-a-repository/about-required-status-checks.md delete mode 100644 content/github/administering-a-repository/configuring-protected-branches.md delete mode 100644 content/github/administering-a-repository/enabling-branch-restrictions.md delete mode 100644 content/github/administering-a-repository/enabling-deletion-of-a-protected-branch.md delete mode 100644 content/github/administering-a-repository/enabling-force-pushes-to-a-protected-branch.md delete mode 100644 content/github/administering-a-repository/enabling-required-commit-signing.md delete mode 100644 content/github/administering-a-repository/enabling-required-reviews-for-pull-requests.md delete mode 100644 content/github/administering-a-repository/enabling-required-status-checks.md create mode 100644 content/github/administering-a-repository/managing-a-branch-protection-rule.md delete mode 100644 content/github/administering-a-repository/requiring-a-linear-commit-history.md create mode 100644 content/github/administering-a-repository/troubleshooting-required-status-checks.md delete mode 100644 content/github/administering-a-repository/types-of-required-status-checks.md delete mode 100644 data/reusables/gated-features/branch-restrictions.md delete mode 100644 data/reusables/pull_requests/about-protected-branches.md delete mode 100644 data/reusables/repositories/include-administrators.md delete mode 100644 data/reusables/repositories/protected-branches-options.md delete mode 100644 data/reusables/repositories/required-status-merge-tip.md diff --git a/assets/images/help/repository/delete-branch-protection-rule.png b/assets/images/help/repository/delete-branch-protection-rule.png new file mode 100644 index 0000000000000000000000000000000000000000..3cdf80017b0f1ae9a10f46c1a65725f934d0cfa5 GIT binary patch literal 9749 zcmZ8{1ymeM(>A&|3jqSbEl6;J+u{-+1b26LU2KCBG-&Vy3&GvpLU4CoEVwVu&%N)p z??0z!r)FomPj^{Y*HaN6-pgR26Qjey!C}eCN~*xYAzVMxAXLEfZ_b#bL-V^gYfTW*k83MywiJCqw5Q*hSa=vXAv_i+l{+}^b6 zj6Z^B3S|73opBwT)JA8xMNb^gKxK-3Q}4Ki${b7c_pG1ei@8Ue(R|ORWa=zspECU~ zM=akd8$&kvgtNAK+OkJuq|(NMfX>+o35Pn^3AlXaU;dr6tWlh3Do#HS-Vxma7z{?H zD7hQds&5gCkF5?)0(o6U)Z*iw#M^R09KMk;3SC{BSz6lS50hE9PP68}mg=UYEH~89 zgTz*ldL50kh|>HclRpR=I4bh{R415}pOR86-gUALV#nF7`L+4tnWUnhn8OBn5t^^z zQjogjCQVg=1Ud$KMov96>T6{r(+RF?Ht*}%GtSrl9S}l=q@YI~g2N3Ti~sF$q1IO7 z?2ZYix@H}zhd}} zc1^+7Xr4l`Nbb8Egb)zGu%l^!TDF_%1c|+n*c^!?-c3blE|Z3 z`vhiQ>~FaaZwC70(39nH8CHOj;WMHe^ZCew-$&(Oqy^zI#_ah53+oz{zV(G2K`O8vLPmlxz1oCxPt*43& z45KsU1~0|cx)k)popcnu%s$xHyScAV=1=l_ybBwd7jd`wLJD$z(|B%~SC}=Bd9bqC z#mxJx^Z5>uqAOTAFrY;0?6w!G$2aOAOnip zQ&mS>$?d|+0W#3+Xxd*K7NthOfi*VrADPSU5xN$18{&~APx&*USkJZl^NwjqJ(2lx zg%z;lcioIv1V8lI6>SkG#r+QU=hPy#ops{; zwJwuC42&F$a9b=&pwDY*(JR=q^*&BoRypWO7J=vE>93CrJtgpiBxRS_t z8&Z;P$R^d>>pZ&Ew5p@4M+n?lIjTg z$*SKJs6KL6^!EQtYZ|~vO=_z6R$3!OKdYu#5%$zs7#>xb%rA{km0@|R(Wh5H^t zLT7v)VhS@e3kDVh+ICk%?00oLO?yuj0P48JI9v`S5{K z2AkrY7m=1hgOkAs7nc=KA~!?C@7;|Dy%1{`RTuBPkEWW&KugmNF-0+ zwZY_aH^O#Hn61iN*JLi~Slu?0q(n`%9wC6i-elo>0o>^G61`fTUo|AX2Q^o$qDI|N zY~bw`8Bi|NBSI`=Lq~VI85<%fQI1A_UAg8d zyG@PRfA7(2tS>}OgFKW_qZ&J8Fa=8*8wdOZ)Pq-=rUjfT-&&4*_QjHid_@k@I`&dU zUT*R34v9=fF(mj_vyU%ffm#G9B-b!(|G=&?kD29$>fCcdlZV{jwLu2uM0)K0X&HVJ zbO*C7mx#vu@iHZ5eC%W|TM*nwhRo&;1~=nf6Mc__Z?@Q#60MJ#S0sR0d6j4vV`U*F z7oNJi?o2lUFdNi0uwsB6Ig5CERJ_Hd>7YE=SN~1~LK)x)&Vnb`%4>tx(hMWwV}qQp zkO!iiPeoPie#zSTq4zmq09dKb!Ug0MKvNWyG?4hmdR1OK-FbwiTO$P&9`kk|&=9g2 zeEz~cjYcM7st;q*ESHP83g6k;8MwiSR?${IO76dXcDlg#`kDI9`>xgb)BK$U$w_po zW(((TyN*VmX1@B|t{uBAD7mCyw2YUuAOGOC7)~p~#VB>za|>eDui{g|2>0>ri(g*3 zOE%L~NLp(0hJK$pE%qUN{2}Gw(&p1dRfpk5$p9FkbA*J^-j3yv5=|^I22t}%$WW)x zi>iA)N12z+O#=F+U3I}^rsl!hAD%Ztc`tLw^$_kITd5(GFH*kTjX)jEZ$WQ%twojk&j^_EwYpDEgF%eozj zdVbWC@iIrdvc-`4FLGp+8TfFSq`754=6w&{MawaLUR<>{YTln@Chi-B{24MqXwfqG zrYU7&Y{IRSdQRci>)j^-4|f@SLmUIDQ4Az|YP^myGc=0e8+Z5H=4?jGk*vvMje0fjal&qN+4Io!)h7s-AG8@U|GjpL z=-I3_!&Scs^D8;u^7O|oU6lsYPl@z6*M3%WLNIwo?_0EiCK;?g$R~vg_HBgr3IVG&yXmL!*GheH<%YrosHc^j z3H+?7{a91eY={=qVyVE5JICS_@=KQS__2Df$F_!=o(S)ZNhI#QD5WvVBcKi6cvr}$ zd|7YfHP)Vh0-tSTqTsuc`0gsN0nVZ^r)){Uv3Kf8tfyX!Prm@`Olt=PdhqeHPwu;n z$*=V| z2d~7XcpiPGCkHc(ubVbK?VcuZ=K7@JU7PxR!+jaETD9tPyNuXwO~Y*Q)0n2!B7D31 zm^9^3m-n6djoN&xXZA`z@7Ae|2PR`SQxUFKqe)1cnaxUvSh$m{nfyz(&o{NTBbJeI z#$M+fldH@4*Wr?Z)4rFVTncmL1+dBD)1NL8e~b8O{CGO5{v2Om(A2h_K5<|Al-O08 z&TxWTh5%#%=#hgwro7!bzPtH9d^8?aaQa}aILu5)^SH;v*4RR1_UQyW__8Jc^afS2 zQzBTbZadXv38i zP!@yC=W`KG=|Dln?ls3@U=-SpAV?c;tftwrLDbX#ZVwF0&uHIqegG5!Npc51n zYci`^%0%36HtuB7-{xz2Ha4;7RynQp<%pbo1KpI#ELHM7jT(B5lL<-~CPEh*&k6O9 zd+f11dmHQRbl7fg?}EmNGf1cktTsEKtrlA@ggg`D`ivDt^=R=yhiaNiRrx2dysQ!n3&B|s^RQHd)J_c))z7m7o4=z--J}VXA4RpE5 zfGyQQHB+qj_r|@{8HZb%2Ggfugyv15#Ow2%g5ax`mL}Ii-`yaJIQ{0UUG6N`=iupT z0@UD_ZccK}RZVGlHe2Gh!#GzZ=2FXhut(TVoq78(JbSlXKI`;gyBc?uVwiC7YBK+z zn<8$*Q#o8ypSTcZAeC<=S(YCWz`hBR?qGi%pj&_Fv{Qc{5u@G8bA}?KrK0Q{ zkD3&lm9%6Muoy{gc7oZ^AVI}AP@k6 z_NyBjr_B>Z9LpA|E;!I|qgKDxH@9heL|8rSlA4~H^?Ft<%s8nhv`{b90qwVzKbxkR z)KIfr_EASWPE*SDTzA5ZBn3NJgB;7hcl%-^keqA#%|0M zD{I7bCv1DdU4H$3f^M7NTW%Nj%a$s@O-haHuR7en7QzXOpel)Xqh~mkF4o&6PWmVs zVM1b?atTpkC{zk-cYC(rO+O`(^&h)gjP9I4!d;&~Z07>)Ki##g-LmPoQO6233=0P} z8w9A@)Kmroy0l&qYo)O2lQXo5OZ>nEJQN$YGo;kArt>;ZRl1i}DfLsP{ghD>YSXM( zSnw9`pyk9f($_EDOJ<%`jrH?fj3i$1g0m>{&iQJ|Wm5|FWZK9N^xga`)fSzH_o_V~6&&T>W%*ta=P z@_SNNeRAUjcu`DTBOH-24P^kIzy$Sck@~24Q8KS?FGkBR3xPoO^2%Zn`Oo`4>8E*8C90+6CEU!~lUurwqVDFo{4l)B*uJ3Enj3%s{bdzxG{>H_f(Fhah?+#1QI*YAJ-uG}B^M&t&JaO`(O z;j4D*P$Qedb8uW6z4Ds0^`jlZ^>RGUcd(yg_Xv<}aHCf~jQ2(8)@JCbINT^n^q*$} zsyM9vPm!YG_NYJOwNgFjC^8m*WSMhO``=IQgyF9iKx>TJ=!riPiSxfIp01z{wk^@G z6%ToQO^_lVMh4)xP7bA^#7A)t6f;VvvP1et4k*;FMCb78V)~ZAeVt|OWr^#9H(1hn zw!u`6H84?NLWmf`!QlDSDKXM5EJH%fG+mrY_(A|mf$3rF&UIXoO?bf0l>MrV%$To| z*wN}Fb)8(?DYvX*O}N)Rh$dL@S~n1s~O+GQvX&({b(KfLsxuDT>5M8LJ=>1KU3qA#T*_Ne!k z;>3sv>tsM;ANrT9spV{$b`z&qcUzgc^cgZDsla`YVZLk(^Ha`7fzY9-puPe3au_@o zftHqjMXNrve7FPm8(B2c(p`>m2dj@c4sj593WdmBwNbM1zJ_P^acLb-rZSrzkq-Q6 z7U5>67Nm9|0df~Z z!lDMT|};Eyl%A0YX(cG4^lV za9<*vdLEeB=pSxvnU65Vo~_UKQjR>`-C#%%V^!`&bC{#fLu4_DgJ*|cO;>rY`tw?G zGwnsd&cB39#UgYmQJ(k(X+GIUi%FB-RN@ut4YgriNQz+6g?5CZ+-1y=7*kbZMyG!M zOdb6ibiikl1>4Dbsx1cfy}I8BNzs!)+LCaCegBUA_9=~{18+74GT6YII)eX|OFaqK zd7B~@pi>2|hK}{u)%$C{*Ht2wd(&Fqz0?4!AonFaz^ToREi~xOc9Al5A z)XnqXhuk#v&GI(==7`Pa!>uN^n$nwruTxxTAbF(i7qXiYWDmcp8_Aoxns9VuKjht7 z0Nq#PTYpz?i`n@(B~5K|=;(WQH{rKk;|L$hou6ed6|DG+zQd)Ksgy za$VG(SZw%6pTbhjJOS6oe_LbO4VdH!cvxh`|E`WQ$SZUiHL~JLr*)ujsFaRE!5wz} zYxV{B!n@6|^~N)kT`Bb?f>#|*vc#yLj#CxRi_{t@2Z8!@7}vDY}hq(v2vlmrJ36sw&3SD36Msfak&i&qw9op1`l_8qn)TtkmRCmG(v zi=-B)A^g)$8YKAbE<3%o-zrT2>j5`=>h$-xnla=UUY6rOA)UF=eW;i_X~kJXUUiD5 zRhvaDd~_uWjw#O7aQK8M`jhh>%wv zfLG>rT2344!s=v>jOV=B3)U*CmW!*Ql-vG`+b94Z&W|^^kHOM#0NHNSnEMD!7~!!> zM~Qg95)a>FY9zs^gwQ8gOW+ez`#cTkUM>#>ewJMo{IYKXn@oiHI(1&?Iu>;GUFd0$ za8m~4JrmuiRpnL5#lxdhM`hiLO$jP@tau994!9jy7uJ^GEVSeKWNwcszPLk-J*m2fAab2Vw;k zQGokcEcfR~NIjv=PlpzBMc14C`P)nZ`(6I*9WMc+PY)+uC7AXs{dPvRHFdv5Gf!TY zHKRZN4a`6j;Wjp0U0o!QNdZdKk9do7lM47^Yu$H`5Ljz}gsWZu=>V}7RSAujrB@fO zWmYa8Yfp8BZ69||Oa!JW(b#@qpB!gs6ZHXI{MQvCy|kzXU^4gTyBJOrGC~hf(9Xqd z`V@v?K`WK1vG9T*?iVtguj-yl=O4j=;Ar4pq~{G~6y~V9WuebBH$EnmO`|*l^Mj&V zdFWd#6~S^I@k{b^edq+Q=C{{GSTzAASd%5 zjwtJll%k>2c8)bQnV$YtjUSy99}Xs^h%HZ|NbVD0)qZJgUI5mOxw7av#Q^f_htm6p z9W?YaRRV?p#RS$!!MvPr#fdvo&3F7c(eLkmJ5;d#H7^`-BmYA^zjYPAp@!2qiBP*V zVcUXq3BR9xyXeoBhSB638=xiP@Qh3nfshzZ`bS$$6y^RzZRr>x@$dJo8Z6zf9GHWk@~3MgPnRw^}PwpP!OCC^xrL(XIm>-@H_J!yN^h{i9d1kR=^TVTTS6*)3{fE72Pu4t<+M;xKCTTV_l=&49ER~z;9}pFyj2pPyjWM)v z`P$Me;V6-@@pERr%drE~(f1PtPrIA%YfJPf(8IyZTmQh9mrIC~H9vkNT2#K<)=*hn zrRPnb{|@pLVA(yP{<^uQ z*SNZ-W+52EEew60kzi|L%!#h?yx6B#KAWy;oqQeH$tpZ4DY@w`>42-YtTQj_1$PF+ z3H=#fkL^Eza;h5=<>Se>%KLlY%eCSL&9}xPIz$@SDlNS;BCUH#ee`G2E2J=$%Ae`# zG~;X4meWyJQ+Rt`U?_92U)2UVoRi~QPU`5|oS(4S=lX#uXxFEIxdQ*37i5g+H*2^- zSd|nJy2dHONqywOdte}p##-1#lSF#VK><}^k5iy6Rk~wWkqO%-|EDa1HU~+;h+1)4 zP%$t9O_Eq8zAv#7TQKrjYUuxw8XQ`lWCv0q+mR|7Nba{;0#`M68nrlRqY>peM|lk; z!YT7#osgxpMrf-5MuL0NCMRSliJB?Q94)_f@V-#^pW^-x%~qi{S}`@WN=xDA{F#gZ zdYyyDDU&J<*benRJ@j{qvqy;guTIiF1BbzRSPk6D5nK#M9Om?Y0MOM>@6D2FO%KoO z-^Mq^|DSS?I4*d+8`%e7Ful<5`zRA^f1L%?&CSi-sl1JAfbezOSYd|}iOWmLf3+Sj zJut$j`JJwe4fz&3q}}t_Krr|>18UCr)S{=Q=o*Qu;Zp8(148?jMss2^e)KnDp+8gp z|67c#5j9?5LrrW1I2}kqzVqY98`ulxmaUhr(8YAe!`IqBZ7HB;>!3OjTvfcS1|DeG zlw@FRF!An{#whQ-bGrvL+GHb118lL zaZ}-zLzUCH=^J1QI=&mVWIhNbqf58 z6Evid*E3WC!@iy9kmt=JTS0tv$8u2QE#678KzwnS${Valh4ZaV@`oz?Pyog1YJg366QUL-){|B;v zb~lhjRM8J`U-mwPNwb|de^=4?yAy7&I!p4a_?s||Nm-vlyL%6 zxgZXMvc`1|cYel>iw9Gk?u#N{RG=2KcKfnHgPr!BrVJ<1sQ=~Da}|%MU79E_)gGbA zoqhIJtE+Rr9(hcP!Oea=~_A#P^3XhK&4A$mu?B^?(XjT@c(}A zU!U*0&og)C-aB{Z-gAEE%*^>sgr>R@E*1qA5)u-win6>m5)#VkLs<%d{%|%g5q5vb zkX^KuWRXhxsWu-jDZEMo)CdoK&$-|x}ua!tR$`UY0(+FOe=lIq?~Tirs9Vd{$4~Ti1r@kaRk9*UJJA{uifIQ#OGi2a%N zKa`g;J)2|R{AJi5zZ78S+*hMg@~GY+No^FKaHYFzSpDqJ|0ZA|r$s*l*_5GnbW8B* zZgqR|f0q4~Eq>(8?J1tfUuM)ZdHJeJ>P1H4h*DJgn9ko~Py|f8GCopXeM~{&-1pPB zUOiejwZaOTKD}acl#-HyoCAXc_E1ra-mT}WekpjmrGp3?mHb!A(geyBXtvI=@Ho%B zvzPO7bCR}}P7;F(;ompd(B{-bdKnT?SG5$oB#z3+Y{Z_n@&Y5Zm6W`v)ce3zjA{pd-Wlcji|nT{lflNQ+H% z8J%?>6e54Pr@8x~yzQv|q6QC%!`7RSIbyWGvM zMaZchS74}4zerFRwBhT3L%zCCy z75I#w>6T*(A2|bx$OayCGqJhaMG*cWQP-Bt$Vnm*&4=n1*KdzBlIWr3P)T7H*Bf>A z!2Fs&cn_fGO#}e=6tGY@@~GLuZ@KiD_dnU;5 zFdeITk!c#|b^V2hCSk-C5?~f_|wn&R8B;`UbXKtveG8X^=o%!TrVv=FPReW@M zdWw#HxWYh^4(&yi>PDqn_vA-KH??Z5O+8wf1JEL@3?#CRd=D7~ZC z1=)H;)ZEpf#+&fYIdiM%!Kn6MR%`raR4B-F*~+WHA$CR~Hk^pcgrE>}27}3qcEb>; zt*MHyta}uD{%_~-kJ>lG1JpF*$(ACCUp)`O!4u+E?;RpxU^?BLI(}RG2Oo@_C_-A* zn6@qK;E2dc$b^Vm4i@HRVO;&Z{8zqxs0u1vGEmAVKL^l;hJ0s?;(4)9%J}uao!A5h zs2PNGS=1&euTEByzIE8=y-v+7&Wnp)@aj+JYfV1*mLF2PC@!D|IxE_N`sra{ zvjrZJcbpH&zi^|~0|HU-y%~ArXFNguRy%ku`*(6j5Q!(2YdCT~L@^`imD%M*@ud3P z?ud-d`()jhGIXo!>wI+m=S0`GceEsUrF3U!?nxH4c_p|SM+ztF3%_VjUC$2!z9vRu zVS8dAMXKeVn2SpWnTA5Xn7+HAh{ zUfWpSEGZ&|TSMk`{{?oStF*LoNnWAIC?vbs};Dzv>QF{^(nAmaD-DmtayUTo=XDuve!;hX{o@g(-Ak~kp_ ziFdZQbJM`HBQ1Ou;kZWdyhyC5NLiskl7n5l;jqVtiLxQBt5xsw+pGE%E+ zE7~3!=g{SC%e5l>?R@KnPDuSAxetzI8uN89*7pu2qj%V5G*2$2F|H0NbUKaCtHX8* z&n}F&T90FYFc8A=TsgS8KTn-f+E^J*DwFu*?KZi@2xSDVTWURH9J)EdgndC&Igh@L zCHPr@y*?09jLx|~Q>P}JnhIfF1PKb6TKinLj2$m7vASd9feyOGuQT=n~eS;A# zExx2LAGr#yskV^!MOIou2!iV04IHmc;WC#UP{>7kdfAL_z3n-IYz(%Bog6Hp_Vo1T zu-x?0pShQon7;F)jRlFylenx8O86tT1h*lFUA>>&7Gmt-etke|u=VZ_id3Q5+AWIp z7;qGlHtv8JcvakEHyfu0A4*(PQ%**m=Z-gxHsH<5mZd}R-9(+l71rvjDLjJZ!HJ&I ze^piUB$e!?`=!O%P}un=8cV8A!zN?Y0|sqTT5J7jG>LPXVg_bN>+fb7k8-%p$`h=T z2Kd}1*Zh7suO=AwqU?-~ek(|@8O|A_L&~)JFNTQ~X$dW0{1H{GPeSS$tUkYPdvgx^ z{@yF@?0CJO!oh>U8{r@%NZ9grY;1&rS9;^!TVdc~PT*Cp(i^(>s&VR6xGbpmpN7!U3XO4|;H~E)OC4H}mtHIt@fLvPqBV5_(HdNF& zuW+Lb!`0QQ?{AAlW2r?sN7bgLhb;lOpSg@YN8K_HZ-Rfx+0Xy5v7M~23nMQap^;F{ z&(GI2=I@)qKOd;H?$d4h`a_Pus|uM%Sdt9ah>x}fpAWzfzFR~K&cdY>*0Qz^BM<1! z5awY=$ep(LrsV7PGfE0@ygzJc6~Kx?)}Eh$#C$wjup8TPo>z@ATa2(E>$gXg{&DJT zK}g4-#6dt?#s~v5_0Y`C2-Sps6#~KasePvIm=z|cPJ6IL?@npDVLmi;)C&y^FUT~c zb925)2DH3hh!4}%a&&+rYi(UXcWPi8sZdLw%+=KJg`P`wgKwhHWFR=5H{mBX2PyZLC&8o( z&tC`;?!!VV^(TqAwd)|=g@&PD@}KpMP&uO4fz}K@YI;2r?|-6eX6_hxZSZQkHJBDh zTK=hMI)(t>Ms0;*CF(Xt&Y;ZHi0+-iAc=WPACjlF`W z0gDFQ>Y|kL0-5!_<^}w!sDV)H6zcg-9kq$3eqE+4seZ>FDKmS5*=F+=MZGvp2$J ziEgY}5=S0lsqTbD{ioY8@Yid;Q+1Z&vp?L@Bxmo*eXot?SCk`?72K5Uxw~%BF#Yal zF+QYZJu@6;aA{I3nOXT5EnY;nl->!lQ^i<4wovEvi!r8R;PdayrUne{q!U=A$MYS@ zc3bE`#^~-c;wExuEzyC_?ZvT0z!e%CoVUWZd21{h8_liPRsm(@_5!P9#K{x~6;Xas zWcpe%TG@4yc2lm)lSx)G7Ye+&0pu}Tg71pL_ZN-6IzTtQ)WHI@O=e zc;37~Rfi&BX52wCvi>Z=#{*UlV03N`&)I-3!c3E<9c(Kc^~^#R@h8?ZV#>Lx|5*tD z=}`1bg$F~PQQb}My9fpB*v)HqHfFVk@hV<~7e>kyv`3L9`_>Zlc%EFac^y}i#pJSn zLATW1lt;a{dr_UfHcRVRx%$n;Z@ZmEjBP&0N?y|NPIqB-4`+Rag;K7`DVs<*?fx zmj5UIs5&L)*GY-mXEUO@nw6m*qmLI~G=pY+chEe^`U~K^d47+td(05(qCY28!0nAZ zGq#uxMMlL=#vH6CyGua`dFugo;Y{b+N2&H|L5!`fFikvwGOH}ae!ihy9I@h*Ic?Ps zOX4GxsiV77h)DLe5lHar=eH{7B6_hC8Vm%rZF`gpgRV%AC37bdKNsdr03l!<;Sl`opSttC%bY3H9-}ny0dx)Za|Y z8l+i)vMysKUj-{^lYPq`Wy>*vo7fiP^6motI==Qn*W`19XG_-pGmZknnlkFoH%=z8 ztFqm3xsrvGu0(te4+fV{CYxJNdZN5r^kCb!&-6-#O(;i;Fi(;+hM@ zUgYv>+ALpq9uka^C5f?JI`2LIEhSA=o5$#uxS=YIKZOiW%I@=AC7I3lkjn||8+Bg) z=nx#fqJ2rHQ26n>)^o80FKA8^QIx`aeQq=UIU`OS6YXkOoQ8gpqsT~4=C$i%)N3_E z&JPM3=(6tWPH+TgOPj3Wp~&%m`lqAzX4Ewh0C9U`?gkv5?|>3Huek=RcGwj2QwYVDfrXhzN-wohX&OR?SCf#_vf$DI%%_HTowIoWjGi$xo&z42a z8rEAp?a{|6PZn0OG&x;kn+LwT4lW}HQ!eH{o@lBxsjr!WLR|&4E+O;CFRCrbGbH>6 zq1T*dKcLUcgooI&cBGWwJufw9F-f_+4xNN5!LpJAyQa1hpOm)L(zPVMi}B+Tb9me= zW^aL$?!TNNH2%$`?`2xk9%uE@ys1xeft8wIAN%pGZ?#)ppU}dU?OB(s=J_q`EJYG+ z-x2F-qlrvORf?oi4tPbI2ly^>P3#8C0^98b^>ZZgcNgY*(Zx6Bz}1(vzs$n={l0Qw zljd$y>Ey0-e(@yBW}oF+_4e70#Qo)fU(aGsLsukUOvi<6sBjb*%!^+E&&k9Ih3 z&V6#QK;S77ZI^7l_5*@6@4qbcn!ms9rooEGaOI1_z~=EzyaRMRxq^%*2adb_Choe( za^L#1PiN;fTbOmJ^H=>}3zg5AuW;8y4QJ*rDc`Yvbp;c!m9WdZ@$F@Ly$LbVa5Se> zya@=$pg5eVv7K!gmJ}=>qZGCi$|KEq1tk}05tjCnad)By`2a{wQ`?i)YgS{qUEtqoILcE@xnoTahlMtOlqUeTn&83jB4FA z+VcFJCoPJA$07lYL1^yo?lAi3U!_TIqMlcr#U_X$pc1fGV4ZttEv7oqTE90%t-i(~ zn^M?en2uSbwDBg0JldSH?H$#}D&L>XD2l)ADDZ{Sofg9JlZww{sl-(f@WdngG3sEN z^v0_pkibEcORc4JbLDUtjJn`6W$hcx_Y6kqLa6n(U`y?ORP;Dk;6iX1EVUV@<*A*` z!=g9OxP;_le68BU^+zbj?5d<}WA1#v$#?lI8ZoOWx9#Eg(Ufz@6Cvcty*sogfMB)- zG$RlDY1J58B3|^Ou)XA6nR{9==7pc%1}oz9ibGN1SiKyBe1c&GU?LYtO>Ocl(i<_bG|ksN>X)tXO)q;^kUw@F9*=o%vb$x0iqEH|uEZcp@^Am_@^{|EoP2g7t8b9q9(7ky}F*%O$tAizXfB3kC%m#y}m97`Y zX4EG!3^txCg&etPcmD*Xw_hG6$2I{?NLJvKyx=#A90msUAg3Q61Df^ z!pA*jz=knIMBxIp#Zp>QhJStF>!)e>#B;RWhv|buI@bZ=e4R%YNNN?Re?P_9%eo*2 zZ%$TeGH+Me%IBK6h_myx9~Y7ZFkc=-b1EV?W1*ac_l8+d`T zk3EL|?W?KamT!Cmw0K~5sy`k@GD9ub>0+Jb{#d7l?r2`>PUD3RA{7rLrs{tjyg$5u zbLNm@G!DtOwPf(Fpsr}B2^9vWSkCn&nRyL5c_e6v)__2lbf7%vbxoSatjp=GE`hHj zRKDX5zmV>IL{xmuhPir5zU0~7izoHHYRDo(ZROZs&2o$L%A-9>e)M=LYqy0=bSKPO zpZ_xB&GoAHlP*+8eEd%=Miz=&5~^F*5aQHu6o;NjlCQn^I`mrwVlgzxa0mAP1h}Fx zknzQhq;I6lm`+}TPqoIls#;CWr#nEeaH!@k`;>B1_ZHmrfz!*;6e^B!CN-RaMsbAu#;bsc~>#Ii+ zr+w_$7b+F!=(erh^U$s9N}G4iTE>ABvc5+1Xf-oz0M zEJoQ-fAr9cjGiSA&$8L^ag(qu%rJoL+jJCJyox!GK5OAUYhFBi{w_M5xEhZ+8aMB< zVu?Bxi7@^_q{gUN5C0GGI<fJZBmDD!6DD9-O6)8n{LySPub>WMeex=lgU1ygkQJ zafERq(4W#}$!2ITd6o%)LO4_ld>&X9wXG3Z!!c~=Fj4qEfFV%b#TXtCj=;$Fw_g{k z#Kv5jN)y46N1L;YQ>04@uO|zN;5PwJ$oMpN3lwqU5MXmvQX3fKz^ZkCutwWW!aLxK zj%n#HX)@8gYPzpR*1JNt2;teIFO{-ooj4Y_v~K!Ye(4FeBsTU5E>*p+7u`)WTXsy_iC@xL zft=t@Dvcy-a)(8b0+J%>fjnpjev1-1TEAn6v=nI1iw)j}^O1@LJ$YH`wc{6jfCVv? zAr()apfPVK$OU$IqZkUM3{8B9a34$HM%FJbWl?B10wFVAQ7#b0daby&> zsL&0(nIH;0f4!lTD>a7e^WCG7+~<=oaMzD{$lhW)+L3Z1w!L$M(pDm}z34S}6dpnB za4$A7Uzf}@?zc`Hyf6T%L#!Jhe6TYB*Im~Cq&n@>e1&Hyjj7iHV`b$8)>;w<#O@|J*S>4ktnj3n@nKc>u zhSkcqt5{dH{`dG|Uf(inD{e?$hNYQnKYyWk+NtqtQ^2}!K(@@eyg_ni0F`deq2Ydw zdTZ&FdUhvX$rur4Edrd6ab82pxoT=pF6R5}O?hK^Y1&3=Z%)?Xkec?%oxJq=0T%hoH^36GeY}&J zL85G8l8UGl z4z@gU5d}4l07apNH=(BiO;Ir!<}+yL89!F3D4= zt4^As^Sc|K&3gZXFss0wX|r4Y(Q%q2i`*fe##5$Bk6Yn}Q);oRc5AEb-9i*6@aD~l z%baw3t%h%ZYGQ-$*6pqF!3^Hkj7Oa1oG)s^4pS7wIxU1@>f-0>;eHq$UY5=MfsPA) za3J`8fB}40I6mwcyL{s5+uz})d(z`F(v2EE$I&3;3UY76ten5?lCw zM&}u8EqUVLR2Vw#YlC5G4{2iZ1C7hz$q1DTvYfQM5TL83Jw2#syd8TN8n-OArNrLE z9)lkJjqms(KY3$-1@JRtuZKuveG1@JXLsJO+(ghz&;on;+M!r;3n=?DVmNugr{tj2L-tWZL;sGL?SF5hQpie?3;jrNt;G=78~`ZZ5J)b>;oNuDQYEpR>Z;u4wG`w3msjq9H6`?f+z>F% z34oQUAm2&L3m_rOa(dbr;{6M`hBek^dp5r(lHI`p30Etd9HajUK|VNWHG*(=Z1upO zw(I1KdFYwWK=0oKl(Icq3mP#~tzVF9OT9Q_6mk_&yl&~ronvrLh%ntNF4Z>9*8NUM9#)yBSP}|7_>Pt z-cVgFXgrwLNaGj&{({;4I4Pstjk#tmy>LTzGJ?MF^zZ(ZfoNrkjFKp!JgDdVbv)ec z{MX-=#8{Pq0PQ-RyxUmQ+{qJG4-uFOQU z=R_NEkv#e^To%15n*d(vP7o+b#)jf|t}aGZ_yiEA@$^(6zQa(@e$pkYP~g>f|KO4L z1K(1p3p1TA0*9{u-CXgTKW!sNPMc9N4KF+f6Y6OyDcduyzAuV~tj=m5Gg;!vRHz8p z5^=uo?myi6g8jNPD*5Bz`ZXs6mUY7+nJkOtnD>C@mJXK1#7wkDi6a^)T~~mAxuV~; z(h>ZdKW(Ge%a(qFdr;=|)Wh~(Wi}$*8rGy-rnphg~{0{`NE1^!{AK*!;0@gG^n@d5%MQ`en8MYRv5>*KE;4ruvH zc4Fl0S`~yjlf0?+V4o-VxDFSt%9hczcv0SW-cj4<-v2T}zm4F5X_b~<1MMz8C52KYhs8JInGfEMYbazON9o-hKAx53jUF#bZ|Nz zEeXFAfM2Q$qYEDAwIp;~{B+qlQ}fNW>}%FIb7=D zX+FzTD1_KcvBdOwB;#%GVI!W&EqDGq?z`I&AIQ8FSjvah1CjefCLTnZ_pK_Bczj6Z z|7-gfARs&_9GmWuCy7PuI}tMNeZ{qWTUknSMbUEVqT_&D=f3`Fx0WYa6}5>Y1-9c~ zUj79YPC&p1EV?8(P;Y{E1@wAFvIM(a2}Eyq(VuW^Hf_JMYJ6nR#+m5c@8g`q>sNeF Z^A?|q%ptnJ^!I)*6$N$q5?S-0{{fjqax?${ literal 0 HcmV?d00001 diff --git a/assets/images/help/repository/save-branch-protection-rule.png b/assets/images/help/repository/save-branch-protection-rule.png new file mode 100644 index 0000000000000000000000000000000000000000..a0e8810aa9712978d46f340c5d6e9ad14ab4d543 GIT binary patch literal 3051 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91n4kjy1ONa40RR91H~;_u0GW7^K>z>?RY^oaRCodHTnThkMHanDH)J&l zgvAI6AtYflCb_g=y{hWqRj347Gy{Tx5FQ+6sB?x1 zHek^x9Li3CcR&T$3a#p+k2DQgz(X5(D`(;DWr8ic05Jg(_-N4UhI(o!2V+<~ka-MV z{w7#dSk&Y)guO>MqD^UA+W0`$G0^5l#1O$gPuc`;e>1FwHY4xUZORb>w6V9Z8ML_( zF+{M#=Z*s=9TJTIUM}013n4Z)(0M}yld!1sc>{2l&n7lyYuen17$TUF7wI;COawH+ z{+M)3G(}2S=GF-1Lj?f~x+NF@Ec7p3t3g(+9VDum$l`gJVpKF$z?=?$hp*YE+<>S%T08=7^I&Fg6BruvEctkG$6V>*S3m8<@e3!> zzGicT`B%l!3#qujUM~!;*Aq7fR8dQ1D-zEh#IOy|p--JIc&6#YSax_FrtW-0+BXc1 z#((0c;k)#G7_o688dR=>X|2Z~{H8Ei3N1)FmyCzkKZktlWv7S?i0O*qarYwBF9esZ z1=w|ZKOXz?1$9z!bwhdd?f2u)b^nA4CNsW0m59G>n}xHv=SAP77Nb<(n<3ceCK(qe z&dl%sEzcNU<7>6STl37KjW|vtYz5kn5(?0UA*8WCDbF??CWN!9 zv)^rLyM@RTnh!^dn{Sin?{t}pT0ys9`>EaPvj?#uk$9!;GxE$`UvBeY9Psq--ooTo zqY)WYLnY8pV2YaMKPoRX_L~_VyT(v$fT)u>q3uyvq zs4`wgUM5=K(nJjW;i1(S*04W(Ocn9wz9snQp7#ac6+P!7CZv`aF}on=8q8^U%Gk{_ zus&s*kauOT`J%sQ#c^9+6>^6tFZETzLbR>XOdh9YpTVr%3-Nx^XW}904M|uoUcOA- z;ZU*oz$#4p?oD-&?1k?KEkj(DSb6q9gT8Vd^UXADJh4Mkg-!k5b&!h>`>H&U9>2>c z56J`|4xB^}HtZ{eVlI2xRv;cPN9D5gbR?WR#jONeo3aHPQ@7(`MTU;ycOte@q=dCk z6%m>(PLP>Qul7WfA&9)Gh68NQYRbnd1U=d00Sv6$9UmmE1c}CQ!0^_%T79Y0FFGDQ zqdLfaW#3@Awhn6yzPqS|2ZkxHWEFC;oF2C8@?k}*$UQwLB~y`~Bn?y^hr$p>Z~U)L zlf+vwOj7*KzH+sHeerX99ww*foCU)gB}}CNd_T!W;TU$NCrY}&f0NLhFs$=guX!wT zNOW+7-0wM)gr?PR#g+k!kaF=P)*j!2d5Mc0_1tmeR)TTBG$fOIehA`{?ysSme<=E@ z94ptFFP@FYNWF9lC$mpqv*KKQaFviRKB6_OHk;r_qEUQJR~8B9^0L5{DTR3r<$V4H zxfcDRNBN~+92Mf)^H+lzSKB_TCP@qNAoQ%vkAf=(7JY@>(*xP%mwqhZ?R7PS z@%x#m#LGSo>f!xQ+3BK^x#^>EgCtbbb3GC_0DYo6qw}(%_E(nq)olc0IGf#Wg32X+ zz{pLLW#IG*J5TRJkH~fi@eRU|s7_KoX!RKJOeEgAK5sifVzSPBrEaC#=pNbj%IrS+ zr94l}I4I#~`H}Tln6yI5qJqQ0*=|p&9g5TqLo&nXt)Vg4mvKlQ&1yGZywdOu&lj!g z^uE2ywP^fii~7s+A@zHUcXe9XNnu*{Swscb#NBEkKrcyeNN;2phG6RF=e{*h+lwUx zlVtSt&8o*?<*`kev-bn>tjukz`c+nX!;zeI!qKKIZ`?*O5{q(Ijiz97%6%^;rCn-W zN!mX-yj}o{P%FTRE&d`&Z9>f5H(;|! zG=GiI8Ua#rd!dvtc)TsV-t9D}RGnvsuvkFWmC>f9D0i}v)i0)kru#mTQFMse+bE708R zH7eZWG9rN$0+66qyxb3CUdeM=Zp)CY*XK_p4?T2o!hFqB#3KmiDPXv>AKZ;ERKyw5 zpbvOPn`6n9EsJNj{KK8yD)GBD!AcCF>lE;4iJ#w-xGl;5J%OmlQal2N2*z_Zl|>e> zRX_QCA)st6Ha9RTLj;Qosfj|XCYS-d%ViVVnl?8gh6vUvvL)0xj*<82HsuikWoxmy zfxa6e*aM9d5FHqy{;b^CpE4Qfr*7gV1ZZR0nl?8gh6olA;ExyDjz)}MIBe%HqcBf- zGo6ze!QV66sE|mT(zdiQZB3gS5kouqe38{^MOIc8-b-A8O({EMSJ~(vXBz3aZc};) zFrnv3LHme1abH|71P2GhWHK3gp<#mA-iD=1h?;(+D_2KoiUvD!R;N2xx-23`(uY83LMM&QQ^1 zE<->Q%w=2.20' - github-ae: '*' ---- - -Anyone with admin permissions to a repository can enable branch deletions. - -By default, you cannot delete a protected branch. When you enable deletion to a protected branch, anyone with at least write permissions to the repository can delete the branch, including those with admin permissions. - -{% data reusables.repositories.protected-branches-options %} - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -6. Under "Rules applied to everyone including administrators", select **Allow deletions**. -![Allow branch deletions option](/assets/images/help/repository/allow-branch-deletions.png) -7. Click **Create**. diff --git a/content/github/administering-a-repository/enabling-force-pushes-to-a-protected-branch.md b/content/github/administering-a-repository/enabling-force-pushes-to-a-protected-branch.md deleted file mode 100644 index efb82441a0..0000000000 --- a/content/github/administering-a-repository/enabling-force-pushes-to-a-protected-branch.md +++ /dev/null @@ -1,33 +0,0 @@ ---- -title: Enabling force pushes to a protected branch -intro: You can allow force pushes to a protected branch. -product: '{% data reusables.gated-features.protected-branches %}' -versions: - free-pro-team: '*' - enterprise-server: '>=2.20' - github-ae: '*' ---- - -Anyone with admin permissions to a repository can enable force pushes. - -### About force pushes to protected branches - -By default, force pushes are blocked on all protected branches. When you enable force pushes to a protected branch, anyone with at least write permissions to the repository can force push to the branch, including those with admin permissions. - -Enabling force pushes will not override any other branch protection rules. For example, if a branch requires a linear commit history, you cannot force push merge commits to that branch. - -{% if enterpriseServerVersions contains currentVersion or currentVersion == "github-ae@latest" %}You cannot enable force pushes for a protected branch if a site administrator has blocked force pushes to all branches in your repository. For more information, see "[Blocking force pushes to repositories owned by a user account or organization](/enterprise/{{ currentVersion }}/admin/developer-workflow/blocking-force-pushes-to-repositories-owned-by-a-user-account-or-organization)." - -If a site administrator has blocked force pushes to the default branch only, you can still enable force pushes for any other protected branch.{% endif %} - -{% data reusables.repositories.protected-branches-options %} - -### Enabling force pushes - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -6. Under "Rules applied to everyone including administrators", select **Allow force pushes**. -![Allow force pushes option](/assets/images/help/repository/allow-force-pushes.png) -7. Click **Create**. diff --git a/content/github/administering-a-repository/enabling-required-commit-signing.md b/content/github/administering-a-repository/enabling-required-commit-signing.md deleted file mode 100644 index 44f1fca1ef..0000000000 --- a/content/github/administering-a-repository/enabling-required-commit-signing.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Enabling required commit signing -intro: Repository administrators can enforce required commit signing on a branch to block all commits that are not signed and verified. -product: '{% data reusables.gated-features.protected-branches %}' -redirect_from: - - /articles/enabling-required-commit-signing -versions: - free-pro-team: '*' - enterprise-server: '*' - github-ae: '*' ---- - -Before enabling required commit signing on a branch, you must first set the branch up as a protected branch. For more information, see "[Configuring protected branches](/github/administering-a-repository/configuring-protected-branches)." - -{% data reusables.repositories.protected-branches-options %} - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -5. Select **Require signed commits**. -![Require signed commits option](/assets/images/help/repository/require-signed-commits.png) -6. Optionally, select **Include administrators**. This enforces the required signed commits on the repository administrators. -![Include administrators checkbox](/assets/images/help/repository/include-admins-protected-branches.png) -7. Click **Create**. diff --git a/content/github/administering-a-repository/enabling-required-reviews-for-pull-requests.md b/content/github/administering-a-repository/enabling-required-reviews-for-pull-requests.md deleted file mode 100644 index 0f693b524f..0000000000 --- a/content/github/administering-a-repository/enabling-required-reviews-for-pull-requests.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Enabling required reviews for pull requests -intro: Repository administrators can enforce required reviews so that pull requests must have a specific number of approving reviews before they are merged. -product: '{% data reusables.gated-features.protected-branches %}' -redirect_from: - - /articles/enabling-required-reviews-for-pull-requests -versions: - free-pro-team: '*' - enterprise-server: '*' - github-ae: '*' ---- - -Before enabling required reviews on a branch, you must first set the branch up as a protected branch. For more information, see "[Configuring protected branches](/github/administering-a-repository/configuring-protected-branches)." - -{% data reusables.repositories.protected-branches-options %} - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -5. Select **Require pull request reviews before merging**. -![Pull request review restriction checkbox](/assets/images/help/repository/PR-reviews-required.png) -6. In the Required approving reviews drop-down menu, select the number of approving reviews you'd like to require on the branch. -![Drop-down menu to select number of required review approvals](/assets/images/help/repository/number-of-required-review-approvals.png) -7. Optionally, select **Dismiss stale pull request approvals when new commits are pushed**. This dismisses a pull request approval review when a code-modifying commit is pushed to the branch. -![Dismiss stale pull request approvals when new commits are pushed checkbox](/assets/images/help/repository/PR-reviews-required-dismiss-stale.png) -8. Optionally, select **Require review from Code Owners** to require review from a code owner when the pull request affects code that has a designated owner. For more information, see "[About code owners](/github/creating-cloning-and-archiving-repositories/about-code-owners)." -![Require review from code owners](/assets/images/help/repository/PR-review-required-code-owner.png) -9. Optionally, if the repository is part of an organization, select **Restrict who can dismiss pull request reviews** to search for and select the people or teams who can dismiss pull request reviews. For more information, see "[Dismissing a pull request review](/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review)." This option is not available for personal repositories. -![Restrict who can dismiss pull request reviews checkbox](/assets/images/help/repository/PR-review-required-dismissals.png) -{% data reusables.repositories.include-administrators %} -11. Click **Create**. - -### Further reading - -- "[About required reviews for pull requests](/github/administering-a-repository/about-required-reviews-for-pull-requests)" -- "[About protected branches](/github/administering-a-repository/about-protected-branches)" -- "[About required status checks](/github/administering-a-repository/about-required-status-checks)" diff --git a/content/github/administering-a-repository/enabling-required-status-checks.md b/content/github/administering-a-repository/enabling-required-status-checks.md deleted file mode 100644 index 4d99fc163f..0000000000 --- a/content/github/administering-a-repository/enabling-required-status-checks.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: Enabling required status checks -intro: Repository administrators can enforce required status checks before a branch is merged in a pull request or before commits on a local branch can be pushed to the protected remote branch. -product: '{% data reusables.gated-features.protected-branches %}' -redirect_from: - - /articles/enabling-required-status-checks -versions: - free-pro-team: '*' - enterprise-server: '*' - github-ae: '*' ---- - -{% data reusables.repositories.protected-branches-options %} - -Before you can enable required status checks, you must configure the repository to use the status API. For more information, see "[Building a CI Server](/guides/building-a-ci-server/)." - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -6. Under "Protect matching branches", select **Require status checks to pass before merging**. -![Required status checks option](/assets/images/help/repository/required-status-checks.png) -7. Optionally, select **Require branches to be up to date before merging**. If selected, this ensures that the branch is tested with the latest code on the base branch. -![Loose or strict required status checkbox](/assets/images/help/repository/protecting-branch-loose-status.png) -7. From the list of available status checks, select the checks you want to require. -![List of available status checks](/assets/images/help/repository/required-statuses-list.png) -{% data reusables.repositories.include-administrators %} -9. Click **Create**. - -{% data reusables.repositories.required-status-merge-tip %} diff --git a/content/github/administering-a-repository/index.md b/content/github/administering-a-repository/index.md index c795ce9c6a..5ed179703c 100644 --- a/content/github/administering-a-repository/index.md +++ b/content/github/administering-a-repository/index.md @@ -44,19 +44,8 @@ versions: {% link_in_list /managing-the-automatic-deletion-of-branches %} {% topic_link_in_list /defining-the-mergeability-of-pull-requests %} {% link_in_list /about-protected-branches %} - {% link_in_list /configuring-protected-branches %} - {% link_in_list /about-required-status-checks %} - {% link_in_list /types-of-required-status-checks %} - {% link_in_list /enabling-required-status-checks %} - {% link_in_list /about-branch-restrictions %} - {% link_in_list /enabling-branch-restrictions %} - {% link_in_list /about-required-reviews-for-pull-requests %} - {% link_in_list /enabling-required-reviews-for-pull-requests %} - {% link_in_list /about-required-commit-signing %} - {% link_in_list /enabling-required-commit-signing %} - {% link_in_list /requiring-a-linear-commit-history %} - {% link_in_list /enabling-force-pushes-to-a-protected-branch %} - {% link_in_list /enabling-deletion-of-a-protected-branch %} + {% link_in_list /managing-a-branch-protection-rule %} + {% link_in_list /troubleshooting-required-status-checks %} {% topic_link_in_list /releasing-projects-on-github %} {% link_in_list /about-releases %} {% link_in_list /managing-releases-in-a-repository %} diff --git a/content/github/administering-a-repository/managing-a-branch-protection-rule.md b/content/github/administering-a-repository/managing-a-branch-protection-rule.md new file mode 100644 index 0000000000..06a6d484d7 --- /dev/null +++ b/content/github/administering-a-repository/managing-a-branch-protection-rule.md @@ -0,0 +1,100 @@ +--- +title: Managing a branch protection rule +intro: 'You can create a branch protection rule to enforce certain workflows for one or more branches, such as requiring an approving review or passing status checks for all pull requests merged into the protected branch.' +product: '{% data reusables.gated-features.protected-branches %}' +redirect_from: + - /articles/configuring-protected-branches + - /enterprise/admin/developer-workflow/configuring-protected-branches-and-required-status-checks + - /articles/enabling-required-status-checks + - /github/administering-a-repository/enabling-required-status-checks + - /articles/enabling-branch-restrictions + - /github/administering-a-repository/enabling-branch-restrictions + - /articles/enabling-required-reviews-for-pull-requests + - /github/administering-a-repository/enabling-required-reviews-for-pull-requests + - /articles/enabling-required-commit-signing + - /github/administering-a-repository/enabling-required-commit-signing + - /github/administering-a-repository/requiring-a-linear-commit-history + - /github/administering-a-repository/enabling-force-pushes-to-a-protected-branch + - /github/administering-a-repository/enabling-deletion-of-a-protected-branch +versions: + free-pro-team: '*' + enterprise-server: '*' + github-ae: '*' +permissions: People with admin permissions to a repository can manage branch protection rules. +--- + +### About branch protection rules + +{% data reusables.repositories.branch-rules-example %} + +You can create a rule for all current and future branches in your repository with the wildcard syntax `*`. Because {% data variables.product.company_short %} uses the `File::FNM_PATHNAME` flag for the `File.fnmatch` syntax, the wildcard does not match directory separators (`/`). For example, `qa/*` will match all branches beginning with `qa/` and containing a single slash. You can include multiple slashes with `qa/**/*`, and you can extend the `qa` string with `qa**/**/*` to make the rule more inclusive. For more information about syntax options for branch rules, see the [fnmatch documentation](https://ruby-doc.org/core-2.5.1/File.html#method-c-fnmatch). + +If a repository has multiple protected branch rules that affect the same branches, the rules that include a specific branch name have the highest priority. If there is more than one protected branch rule that references the same specific branch name, then the branch rule created first will have higher priority. + +Protected branch rules that mention a special character, such as `*`, `?`, or `]`, are applied in the order they were created, so older rules with these characters have a higher priority. + +To create an exception to an existing branch rule, you can create a new branch protection rule that is higher priority, such as a branch rule for a specific branch name. + +For more information about each of each of the available branch protection settings, see "[About protected branches](/github/administering-a-repository/about-protected-branches)." + +### Creating a branch protection rule + +When you create a branch rule, the branch you specify doesn't have to exist yet in the repository. + +{% data reusables.repositories.navigate-to-repo %} +{% data reusables.repositories.sidebar-settings %} +{% data reusables.repositories.repository-branches %} +{% data reusables.repositories.add-branch-protection-rules %} +1. Optionally, enable required pull request reviews. + - Under "Protect matching branches", select **Require pull request reviews before merging**. + ![Pull request review restriction checkbox](/assets/images/help/repository/PR-reviews-required.png) + - Click the **Required approving reviews** drop-down menu, then select the number of approving reviews you'd like to require on the branch. + ![Drop-down menu to select number of required review approvals](/assets/images/help/repository/number-of-required-review-approvals.png) + - Optionally, to dismiss a pull request approval review when a code-modifying commit is pushed to the branch, select **Dismiss stale pull request approvals when new commits are pushed**. + ![Dismiss stale pull request approvals when new commits are pushed checkbox](/assets/images/help/repository/PR-reviews-required-dismiss-stale.png) + - Optionally, to require review from a code owner when the pull request affects code that has a designated owner, select **Require review from Code Owners**. For more information, see "[About code owners](/github/creating-cloning-and-archiving-repositories/about-code-owners)." + ![Require review from code owners](/assets/images/help/repository/PR-review-required-code-owner.png) + - Optionally, if the repository is part of an organization, select **Restrict who can dismiss pull request reviews**. Then, search for and select the people or teams who are allowed to dismiss pull request reviews. For more information, see "[Dismissing a pull request review](/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review)." + ![Restrict who can dismiss pull request reviews checkbox](/assets/images/help/repository/PR-review-required-dismissals.png) +1. Optionally, enable required status checks. + - Select **Require status checks to pass before merging**. + ![Required status checks option](/assets/images/help/repository/required-status-checks.png) + - Optionally, to ensure that pull requests are tested with the latest code on the protected branch, select **Require branches to be up to date before merging**. + ![Loose or strict required status checkbox](/assets/images/help/repository/protecting-branch-loose-status.png) + - From the list of available status checks, select the checks you want to require. + ![List of available status checks](/assets/images/help/repository/required-statuses-list.png) +1. Optionally, select **Require signed commits**. + ![Require signed commits option](/assets/images/help/repository/require-signed-commits.png) +1. Optionally, select **Require linear history**. + ![Required linear history option](/assets/images/help/repository/required-linear-history.png) +1. Optionally, select **Include administrators**. +![Include administrators checkbox](/assets/images/help/repository/include-admins-protected-branches.png) +1. Optionally,{% if currentVersion == "free-pro-team@latest" %} if your repository is owned by an organization using {% data variables.product.prodname_team %} or {% data variables.product.prodname_ghe_cloud %},{% endif %} enable branch restrictions. + - Select **Restrict who can push to matching branches**. + ![Branch restriction checkbox](/assets/images/help/repository/restrict-branch.png) + - Search for and select the people, teams, or apps who will have permission to push to the protected branch. + ![Branch restriction search](/assets/images/help/repository/restrict-branch-search.png) +1. Optionally, under "Rules applied to everyone including administrators", select **Allow force pushes**. + ![Allow force pushes option](/assets/images/help/repository/allow-force-pushes.png) +1. Optionally, select **Allow deletions**. + ![Allow branch deletions option](/assets/images/help/repository/allow-branch-deletions.png) +1. Click **Create**. + +### Editing a branch protection rule + +{% data reusables.repositories.navigate-to-repo %} +{% data reusables.repositories.sidebar-settings %} +{% data reusables.repositories.repository-branches %} +1. To the right of the branch protection rule you want to edit, click **Edit**. + ![Edit button](/assets/images/help/repository/edit-branch-protection-rule.png) +1. Make your desired changes to the branch protection rule. +1. Click **Save changes**. + ![Save changes button](/assets/images/help/repository/save-branch-protection-rule.png) + +### Deleting a branch protection rule + +{% data reusables.repositories.navigate-to-repo %} +{% data reusables.repositories.sidebar-settings %} +{% data reusables.repositories.repository-branches %} +1. To the right of the branch protection rule you want to delete, click **Delete**. + ![Delete button](/assets/images/help/repository/delete-branch-protection-rule.png) diff --git a/content/github/administering-a-repository/requiring-a-linear-commit-history.md b/content/github/administering-a-repository/requiring-a-linear-commit-history.md deleted file mode 100644 index 8ed5e87cb8..0000000000 --- a/content/github/administering-a-repository/requiring-a-linear-commit-history.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Requiring a linear commit history -intro: You can require a linear commit history to block all merge commits from a protected branch. -product: '{% data reusables.gated-features.protected-branches %}' -versions: - free-pro-team: '*' - enterprise-server: '>=2.20' - github-ae: '*' ---- - -Anyone with admin permissions to a repository can require a linear commit history. - -### About enforcement of linear commit history - -Enforcing a linear commit history prevents merge commits from being pushed to the protected branch. This means that any pull requests merged into the protected branch must use a squash merge or a rebase merge. A strictly linear commit history can help teams backtrack changes more efficiently. For more information about merge methods, see "[About pull request merges](/github/collaborating-with-issues-and-pull-requests/about-pull-request-merges)." - -{% data reusables.repositories.protected-branches-options %} - -Before you can require a linear commit history, your repository must allow squash merging or rebase merging. For more information, see "[Configuring pull request merges](/github/administering-a-repository/configuring-pull-request-merges)." - - -### Enforcing a linear commit history - -{% data reusables.repositories.navigate-to-repo %} -{% data reusables.repositories.sidebar-settings %} -{% data reusables.repositories.repository-branches %} -{% data reusables.repositories.add-branch-protection-rules %} -6. Under "Protect matching branches", select **Require linear history**. -![Required linear history option](/assets/images/help/repository/required-linear-history.png) -{% data reusables.repositories.include-administrators %} -7. Click **Create**. diff --git a/content/github/administering-a-repository/troubleshooting-required-status-checks.md b/content/github/administering-a-repository/troubleshooting-required-status-checks.md new file mode 100644 index 0000000000..d07532b5f4 --- /dev/null +++ b/content/github/administering-a-repository/troubleshooting-required-status-checks.md @@ -0,0 +1,38 @@ +--- +title: Troubleshooting required status checks +intro: 'You can check for common errors and resolve issues with required status checks.' +product: '{% data reusables.gated-features.protected-branches %}' +versions: + free-pro-team: '*' + enterprise-server: '*' + github-ae: '*' +--- + +If you have a check and a status with the same name, and you select that name as a required status check, both the check and the status are required. For more information, see "[Checks](/rest/reference/checks)." + +After you enable required status checks, your branch may need to be up-to-date with the base branch before merging. This ensures that your branch has been tested with the latest code from the base branch. If your branch is out of date, you'll need to merge the base branch into your branch. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-status-checks-before-merging)." + +{% note %} + +**Note:** You can also bring your branch up to date with the base branch using Git rebase. For more information, see "[About Git rebase](/github/using-git/about-git-rebase)." + +{% endnote %} + +You won't be able to push local changes to a protected branch until all required status checks pass. Instead, you'll receive an error message similar to the following. + +```shell +remote: error: GH006: Protected branch update failed for refs/heads/main. +remote: error: Required status check "ci-build" is failing +``` +{% note %} + +**Note:** Pull requests that are up-to-date and pass required status checks can be merged locally and pushed to the protected branch. This can be done without status checks running on the merge commit itself. + +{% endnote %} + +{% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.20" %} + +Sometimes, the results of the status checks for the test merge commit and head commit will conflict. If the test merge commit has a status, the test merge commit must pass. Otherwise, the status of the head commit must pass before you can merge the branch. For more information about test merge commits, see "[Pulls](/rest/reference/pulls#get-a-pull-request)." + +![Branch with conflicting merge commits](/assets/images/help/repository/req-status-check-conflicting-merge-commits.png) +{% endif %} diff --git a/content/github/administering-a-repository/types-of-required-status-checks.md b/content/github/administering-a-repository/types-of-required-status-checks.md deleted file mode 100644 index df99212ac7..0000000000 --- a/content/github/administering-a-repository/types-of-required-status-checks.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: Types of required status checks -intro: You can set up required status checks to either be "loose" or "strict." The type of required status check you choose determines whether your branch is required to be up to date with the base branch before merging. -product: '{% data reusables.gated-features.protected-branches %}' -redirect_from: - - /articles/types-of-required-status-checks -versions: - free-pro-team: '*' - enterprise-server: '*' - github-ae: '*' ---- - -| Type of required status check | Setting | Merge requirements | Considerations | -| --- | --- | --- | --- | -| **Strict** | The **Require branches to be up-to-date before merging** checkbox is checked. | The branch **must** be up to date with the base branch before merging. | This is the default behavior for required status checks. More builds may be required, as you'll need to bring the head branch up to date after other collaborators merge pull requests to the protected base branch.| -| **Loose** | The **Require branches to be up-to-date before merging** checkbox is **not** checked. | The branch **does not** have to be up to date with the base branch before merging. | You'll have fewer required builds, as you won't need to bring the head branch up to date after other collaborators merge pull requests. Status checks may fail after you merge your branch if there are incompatible changes with the base branch. | -| **Disabled** | The **Require status checks to pass before merging** checkbox is **not** checked. | The branch has no merge restrictions. | If required status checks aren't enabled, collaborators can merge the branch at any time, regardless of whether it is up to date with the base branch. This increases the possibility of incompatible changes. - -### Further reading - -- "[About required status checks](/articles/about-required-status-checks)" -- "[Enabling required status checks](/articles/enabling-required-status-checks)" diff --git a/content/github/authenticating-to-github/about-commit-signature-verification.md b/content/github/authenticating-to-github/about-commit-signature-verification.md index 4dad3a5919..4c51889491 100644 --- a/content/github/authenticating-to-github/about-commit-signature-verification.md +++ b/content/github/authenticating-to-github/about-commit-signature-verification.md @@ -19,7 +19,7 @@ You can sign commits and tags locally, so other people can verify that your work If a commit or tag has a signature that cannot be verified, {% data variables.product.product_name %} marks the commit or tag as unverified. -Repository administrators can enforce required commit signing on a branch to block all commits that are not signed and verified. For more information, see "[About required commit signing](/articles/about-required-commit-signing)." +Repository administrators can enforce required commit signing on a branch to block all commits that are not signed and verified. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-signed-commits)." You can check the verification status of your signed commits or tags on {% data variables.product.product_name %} and view why your commit signatures might be unverified. For more information, see "[Checking your commit and tag signature verification status](/articles/checking-your-commit-and-tag-signature-verification-status)." diff --git a/content/github/collaborating-with-issues-and-pull-requests/about-branches.md b/content/github/collaborating-with-issues-and-pull-requests/about-branches.md index 7a7b866749..14595a111a 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/about-branches.md +++ b/content/github/collaborating-with-issues-and-pull-requests/about-branches.md @@ -74,7 +74,7 @@ When a branch is protected: - If required status checks are enabled on the branch, you won't be able to merge changes into the branch until all of the required CI tests pass. For more information, see "[About status checks](/articles/about-status-checks)." - If required pull request reviews are enabled on the branch, you won't be able to merge changes into the branch until all requirements in the pull request review policy have been met. For more information, see "[Merging a pull request](/articles/merging-a-pull-request)." - If required review from a code owner is enabled on a branch, and a pull request modifies code that has an owner, a code owner must approve the pull request before it can be merged. For more information, see "[About code owners](/articles/about-code-owners)." -- If required commit signing is enabled on a branch, you won't be able to push any commits to the branch that are not signed and verified. For more information, see "[About commit signature verification](/articles/about-commit-signature-verification)" and "[About required commit signing](/articles/about-required-commit-signing)."{% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.21" %} +- If required commit signing is enabled on a branch, you won't be able to push any commits to the branch that are not signed and verified. For more information, see "[About commit signature verification](/articles/about-commit-signature-verification)" and "[About protected branches](/github/administering-a-repository/about-protected-branches#require-signed-commits)."{% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.21" %} - If you use {% data variables.product.prodname_dotcom %}'s conflict editor to fix conflicts for a pull request that you created from a protected branch, {% data variables.product.prodname_dotcom %} helps you to create an alternative branch for the pull request, so that your resolution of the conflicts can be merged. For more information, see "[Resolving a merge conflict on {% data variables.product.prodname_dotcom %}](/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-on-github)."{% endif %} ### Further reading diff --git a/content/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews.md b/content/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews.md index fd7f06c5b6..cd9d144824 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews.md +++ b/content/github/collaborating-with-issues-and-pull-requests/about-pull-request-reviews.md @@ -44,9 +44,7 @@ You can view all of the reviews a pull request has received in the Conversation ### Required reviews -{% data reusables.pull_requests.required-reviews-for-prs-summary %} - -For more information, see "[About required reviews for pull requests](/articles/about-required-reviews-for-pull-requests)." +{% data reusables.pull_requests.required-reviews-for-prs-summary %} For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)." {% tip %} @@ -57,6 +55,5 @@ For more information, see "[About required reviews for pull requests](/articles/ ### Further reading - "[Reviewing proposed changes in a pull request](/articles/reviewing-proposed-changes-in-a-pull-request)" -- "[Enabling required reviews for pull requests](/articles/enabling-required-reviews-for-pull-requests)" - "[Viewing a pull request review](/articles/viewing-a-pull-request-review)" - "[Setting guidelines for repository contributors](/articles/setting-guidelines-for-repository-contributors)" diff --git a/content/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews.md b/content/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews.md index 66fd1846e4..a6854818c4 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews.md +++ b/content/github/collaborating-with-issues-and-pull-requests/approving-a-pull-request-with-required-reviews.md @@ -9,9 +9,9 @@ versions: github-ae: '*' --- -For more information about required reviews, see "[About required reviews for pull requests](/articles/about-required-reviews-for-pull-requests)." +For more information about required reviews, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)." -You can comment on a pull request, approve the changes, or request improvements before approving. For more information, see "[About required reviews for pull requests](/articles/about-required-reviews-for-pull-requests)" and "[Reviewing proposed changes in a pull request](/articles/reviewing-proposed-changes-in-a-pull-request)." +You can comment on a pull request, approve the changes, or request improvements before approving. For more information, see "[Reviewing proposed changes in a pull request](/articles/reviewing-proposed-changes-in-a-pull-request)." {% data reusables.search.requested_reviews_search %} @@ -34,6 +34,5 @@ You can comment on a pull request, approve the changes, or request improvements ### Further reading -- "[About required reviews for pull requests](/articles/about-required-reviews-for-pull-requests)" - "[Reviewing proposed changes in a pull request](/articles/reviewing-proposed-changes-in-a-pull-request)" - "[Commenting on a pull request](/articles/commenting-on-a-pull-request)" diff --git a/content/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork.md b/content/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork.md index 9b15276e4e..0f38fb1a00 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork.md +++ b/content/github/collaborating-with-issues-and-pull-requests/committing-changes-to-a-pull-request-branch-created-from-a-fork.md @@ -13,7 +13,7 @@ You can only make commits on pull request branches that: - are opened in a repository that you have push access to and that were created from a fork of that repository - are on a user-owned fork - have permission granted from the pull request creator -- don't have [branch restrictions](/articles/about-branch-restrictions) that will prevent you from committing +- don't have [branch restrictions](/github/administering-a-repository/about-protected-branches#restrict-who-can-push-to-matching-branches) that will prevent you from committing Only the user who created the pull request can give you permission to push commits to the user-owned fork. For more information, see "[Allowing changes to a pull request branch created from a fork](/articles/allowing-changes-to-a-pull-request-branch-created-from-a-fork)." diff --git a/content/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review.md b/content/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review.md index 273e360041..0f52e396f7 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review.md +++ b/content/github/collaborating-with-issues-and-pull-requests/dismissing-a-pull-request-review.md @@ -1,6 +1,6 @@ --- title: Dismissing a pull request review -intro: 'If your repository [requires reviews](/articles/about-required-reviews-for-pull-requests), you can dismiss pull request reviews that are no longer valid or are unable to be approved by the reviewer.' +intro: 'If your repository requires reviews, you can dismiss pull request reviews that are no longer valid or are unable to be approved by the reviewer.' redirect_from: - /articles/dismissing-a-pull-request-review versions: @@ -26,4 +26,4 @@ This changes the status of the review to a review comment. When you dismiss a re - "[About pull request reviews](/articles/about-pull-request-reviews)" - "[Reviewing proposed changes in a pull request](/articles/reviewing-proposed-changes-in-a-pull-request)" -- "[About required reviews for pull requests](/articles/about-required-reviews-for-pull-requests)" +- "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)" \ No newline at end of file diff --git a/content/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request.md b/content/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request.md index 4b773ebfdf..37608ef505 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request.md +++ b/content/github/collaborating-with-issues-and-pull-requests/merging-a-pull-request.md @@ -12,7 +12,7 @@ versions: ### About pull request merges -In a pull request, you propose that changes you've made on a head branch should be merged into a base branch. {% data reusables.pull_requests.about-protected-branches %} However, there may be restrictions on when you can merge a pull request into a specific branch. For example, you may only be able to merge a pull request into the default branch if required status checks are passing. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches)." +In a pull request, you propose that changes you've made on a head branch should be merged into a base branch. By default, any pull request can be merged at any time, unless the head branch is in conflict with the base branch. However, there may be restrictions on when you can merge a pull request into a specific branch. For example, you may only be able to merge a pull request into the default branch if required status checks are passing. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches)." {% data reusables.pull_requests.you-can-auto-merge %} diff --git a/content/github/collaborating-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request.md b/content/github/collaborating-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request.md index 577bdf67dc..efecceace8 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request.md +++ b/content/github/collaborating-with-issues-and-pull-requests/reviewing-proposed-changes-in-a-pull-request.md @@ -70,5 +70,5 @@ After you've finished reviewing all the files you want in the pull request, subm ### Further reading -- "[About required reviews for pull requests](/github/administering-a-repository/about-required-reviews-for-pull-requests)" +- "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)" - "[Filtering pull requests by review status](/github/managing-your-work-on-github/filtering-pull-requests-by-review-status)" diff --git a/content/github/creating-cloning-and-archiving-repositories/about-code-owners.md b/content/github/creating-cloning-and-archiving-repositories/about-code-owners.md index fb66821ca2..81e614d5a3 100644 --- a/content/github/creating-cloning-and-archiving-repositories/about-code-owners.md +++ b/content/github/creating-cloning-and-archiving-repositories/about-code-owners.md @@ -19,7 +19,7 @@ The people you choose as code owners must have write permissions for the reposit Code owners are automatically requested for review when someone opens a pull request that modifies code that they own. Code owners are not automatically requested to review draft pull requests. For more information about draft pull requests, see "[About pull requests](/github/collaborating-with-issues-and-pull-requests/about-pull-requests#draft-pull-requests)." When you mark a draft pull request as ready for review, code owners are automatically notified. If you convert a pull request to a draft, people who are already subscribed to notifications are not automatically unsubscribed. For more information, see "[Changing the stage of a pull request](/github/collaborating-with-issues-and-pull-requests/changing-the-stage-of-a-pull-request)." -When someone with admin or owner permissions has enabled required reviews, they also can optionally require approval from a code owner before the author can merge a pull request in the repository. For more information, see "[Enabling required reviews for pull requests](/github/administering-a-repository/enabling-required-reviews-for-pull-requests)." +When someone with admin or owner permissions has enabled required reviews, they also can optionally require approval from a code owner before the author can merge a pull request in the repository. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)." {% if currentVersion == "free-pro-team@latest" or currentVersion == "github-ae@latest" or currentVersion ver_gt "enterprise-server@2.19" %}If a team has enabled code review assignments, the individual approvals won't satisfy the requirement for code owner approval in a protected branch. For more information, see "[Managing code review assignment for your team](/github/setting-up-and-managing-organizations-and-teams/managing-code-review-assignment-for-your-team)."{% endif %} diff --git a/content/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests.md b/content/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests.md index e777541212..15dbba5c8c 100644 --- a/content/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests.md +++ b/content/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests.md @@ -15,7 +15,7 @@ versions: In repositories where {% data variables.product.prodname_code_scanning %} is configured as a pull request check, {% data variables.product.prodname_code_scanning %} checks the code in the pull request. By default, this is limited to pull requests that target the default branch, but you can change this configuration within {% data variables.product.prodname_actions %} or in a third-party CI/CD system. If merging the changes would introduce new {% data variables.product.prodname_code_scanning %} alerts to the target branch, these are reported as check results in the pull request. The alerts are also shown as annotations in the **Files changed** tab of the pull request. If you have write permission for the repository, you can see any existing {% data variables.product.prodname_code_scanning %} alerts on the **Security** tab. For information about repository alerts, see "[Managing {% data variables.product.prodname_code_scanning %} alerts for your repository](/github/finding-security-vulnerabilities-and-errors-in-your-code/managing-code-scanning-alerts-for-your-repository)." -If {% data variables.product.prodname_code_scanning %} has any results with a severity of `error`, the check fails and the error is reported in the check results. If all the results found by {% data variables.product.prodname_code_scanning %} have lower severities, the alerts are treated as warnings or notices and the check succeeds. If your pull request targets a protected branch that has been enabled for {% data variables.product.prodname_code_scanning %}, and the repository owner has configured required status checks, then you must either fix or {% if currentVersion == "enterprise-server@2.22" %}close{% else %}dismiss{% endif %} all error alerts before the pull request can be merged. For more information, see "[About required status checks](/github/administering-a-repository/about-required-status-checks)." +If {% data variables.product.prodname_code_scanning %} has any results with a severity of `error`, the check fails and the error is reported in the check results. If all the results found by {% data variables.product.prodname_code_scanning %} have lower severities, the alerts are treated as warnings or notices and the check succeeds. If your pull request targets a protected branch that has been enabled for {% data variables.product.prodname_code_scanning %}, and the repository owner has configured required status checks, then you must either fix or {% if currentVersion == "enterprise-server@2.22" %}close{% else %}dismiss{% endif %} all error alerts before the pull request can be merged. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-status-checks-before-merging)." ![Failed {% data variables.product.prodname_code_scanning %} check on a pull request](/assets/images/help/repository/code-scanning-check-failure.png) diff --git a/content/github/managing-your-work-on-github/filtering-pull-requests-by-review-status.md b/content/github/managing-your-work-on-github/filtering-pull-requests-by-review-status.md index d712514da7..58bd074a17 100644 --- a/content/github/managing-your-work-on-github/filtering-pull-requests-by-review-status.md +++ b/content/github/managing-your-work-on-github/filtering-pull-requests-by-review-status.md @@ -11,7 +11,7 @@ versions: You can filter a repository's list of pull requests to find: - Pull requests that haven't been [reviewed](/articles/about-pull-request-reviews) yet -- Pull requests that [require a review](/articles/about-required-reviews-for-pull-requests) before they can be merged +- Pull requests that [require a review](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging) before they can be merged - Pull requests that a reviewer has approved - Pull requests in which a reviewer has asked for changes - Pull requests that you have reviewed diff --git a/content/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests.md b/content/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests.md index 4b978b4222..102296457c 100644 --- a/content/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests.md +++ b/content/github/managing-your-work-on-github/using-search-to-filter-issues-and-pull-requests.md @@ -36,7 +36,7 @@ For issues, you can also use search to: For pull requests, you can also use search to: - Filter [draft](/articles/about-pull-requests#draft-pull-requests) pull requests: `is:draft` - Filter pull requests that haven't been [reviewed](/articles/about-pull-request-reviews) yet: `state:open type:pr review:none` -- Filter pull requests that [require a review](/articles/about-required-reviews-for-pull-requests) before they can be merged: `state:open type:pr review:required` +- Filter pull requests that [require a review](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging) before they can be merged: `state:open type:pr review:required` - Filter pull requests that a reviewer has approved: `state:open type:pr review:approved` - Filter pull requests in which a reviewer has asked for changes: `state:open type:pr review:changes_requested` - Filter pull requests by [reviewer](/articles/about-pull-request-reviews/): `state:open type:pr reviewed-by:octocat` diff --git a/data/reusables/gated-features/branch-restrictions.md b/data/reusables/gated-features/branch-restrictions.md deleted file mode 100644 index cf179ece17..0000000000 --- a/data/reusables/gated-features/branch-restrictions.md +++ /dev/null @@ -1,3 +0,0 @@ -{% data reusables.gated-features.protected-branches %} -
    -Branch restriction is a type of branch protection that's available for public and private repositories owned by organizations in {% data variables.product.prodname_team %}, {% data variables.product.prodname_ghe_cloud %},{% if currentVersion == "github-ae@latest" %} {% data variables.product.prodname_ghe_managed %},{% endif %} and {% data variables.product.prodname_ghe_server %}. {% if currentVersion == "free-pro-team@latest" %}{% data reusables.gated-features.more-info %}{% endif %} diff --git a/data/reusables/gated-features/protected-branches.md b/data/reusables/gated-features/protected-branches.md index a9745fcec2..ffae769bab 100644 --- a/data/reusables/gated-features/protected-branches.md +++ b/data/reusables/gated-features/protected-branches.md @@ -1 +1 @@ -Protected branches are available in public repositories with {% data variables.product.prodname_free_user %} and {% data variables.product.prodname_free_team %} for organizations, and in public and private repositories with {% data variables.product.prodname_pro %}, {% data variables.product.prodname_team %}, {% data variables.product.prodname_ghe_cloud %},{% if currentVersion == "github-ae@latest" %} {% data variables.product.prodname_ghe_managed %},{% endif %} and {% data variables.product.prodname_ghe_server %}. {% if currentVersion == "free-pro-team@latest" %}{% data reusables.gated-features.more-info %}{% endif %} +{% if currentVersion == "github-ae@latest" %}Protected branches are available in internal and private repositories with {% data variables.product.prodname_ghe_managed %}, {% else%}Protected branches are available {% endif %}in public repositories with {% data variables.product.prodname_free_user %} and {% data variables.product.prodname_free_team %} for organizations, and in public and private repositories with {% data variables.product.prodname_pro %}, {% data variables.product.prodname_team %}, {% data variables.product.prodname_ghe_cloud %}, and {% data variables.product.prodname_ghe_server %}. {% if currentVersion == "free-pro-team@latest" %}{% data reusables.gated-features.more-info %}{% endif %} diff --git a/data/reusables/pull_requests/about-protected-branches.md b/data/reusables/pull_requests/about-protected-branches.md deleted file mode 100644 index a28b7dbee4..0000000000 --- a/data/reusables/pull_requests/about-protected-branches.md +++ /dev/null @@ -1 +0,0 @@ -By default, any pull request can be merged at any time, unless the head branch is in conflict with the base branch. diff --git a/data/reusables/pull_requests/required-checks-must-pass-to-merge.md b/data/reusables/pull_requests/required-checks-must-pass-to-merge.md index 089efbf2be..345f7941ee 100644 --- a/data/reusables/pull_requests/required-checks-must-pass-to-merge.md +++ b/data/reusables/pull_requests/required-checks-must-pass-to-merge.md @@ -1 +1 @@ -If status checks are required for a repository, the required status checks must pass before you can merge your branch into the protected branch. For more information, see "[About required status checks](/articles/about-required-status-checks)." +If status checks are required for a repository, the required status checks must pass before you can merge your branch into the protected branch. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-status-checks-before-merging)." diff --git a/data/reusables/pull_requests/required-reviews-for-prs-summary.md b/data/reusables/pull_requests/required-reviews-for-prs-summary.md index ef0b0a397b..3526e39a78 100644 --- a/data/reusables/pull_requests/required-reviews-for-prs-summary.md +++ b/data/reusables/pull_requests/required-reviews-for-prs-summary.md @@ -1,3 +1 @@ -Repository administrators can require that all pull requests receive a specific number of approving reviews from people with *write* or *admin* permissions in the repository or from a designated code owner before they're merged into a protected branch. For more information, see "[About protected branches](/articles/about-protected-branches)." - -When required reviews are enabled, anyone with access to the repository can approve changes in a pull request. However, you won't be able to merge your pull request until the required number of reviewers with *write* or *admin* permissions in the repository approve your pull request's changes in their review. For more information about repository permission levels, see "[Repository permission levels for an organization](/articles/repository-permission-levels-for-an-organization/)." If review is required from a designated code owner and the pull request affects code that has a designated owner, approval from that owner is required. +Repository administrators can require that all pull requests receive a specific number of approving reviews before someone merges the pull request into a protected branch. You can require approving reviews from people with write permissions in the repository or from a designated code owner. diff --git a/data/reusables/repositories/branch-rules-example.md b/data/reusables/repositories/branch-rules-example.md index b9cd9572f0..ea81704455 100644 --- a/data/reusables/repositories/branch-rules-example.md +++ b/data/reusables/repositories/branch-rules-example.md @@ -1 +1 @@ -You can create a branch rule in a repository for a specific branch, all branches, or any branch that matches a naming pattern specified with the fnmatch syntax. For example, to require any branch containing the word `release` to have at least two pull request reviews before merging, you can create a branch rule for `*release*`. +You can create a branch protection rule in a repository for a specific branch, all branches, or any branch that matches a name pattern you specify with `fnmatch` syntax. For example, to protect any branches containing the word `release`, you can create a branch rule for `*release*`. diff --git a/data/reusables/repositories/include-administrators.md b/data/reusables/repositories/include-administrators.md deleted file mode 100644 index 6457a0437c..0000000000 --- a/data/reusables/repositories/include-administrators.md +++ /dev/null @@ -1,2 +0,0 @@ -1. Optionally, select **Include administrators**. This enforces all configured restrictions for repository administrators. -![Include administrators checkbox](/assets/images/help/repository/include-admins-protected-branches.png) diff --git a/data/reusables/repositories/protected-branches-options.md b/data/reusables/repositories/protected-branches-options.md deleted file mode 100644 index fb88ecf9d5..0000000000 --- a/data/reusables/repositories/protected-branches-options.md +++ /dev/null @@ -1 +0,0 @@ -You can automatically enforce protected branch settings for some or all branches in your repository. For more information, see "[Configuring protected branches](/github/administering-a-repository/configuring-protected-branches)." diff --git a/data/reusables/repositories/required-status-merge-tip.md b/data/reusables/repositories/required-status-merge-tip.md deleted file mode 100644 index b101fce97d..0000000000 --- a/data/reusables/repositories/required-status-merge-tip.md +++ /dev/null @@ -1,5 +0,0 @@ -{% tip %} - -**Tip:** To successfully merge a pull request into a base branch that has required status checks enabled, the pull request's head branch must be up-to-date with the base branch. - -{% endtip %} diff --git a/data/reusables/repositories/review-policy-overlapping-commits.md b/data/reusables/repositories/review-policy-overlapping-commits.md index d5fba7504a..cfe413d8a0 100644 --- a/data/reusables/repositories/review-policy-overlapping-commits.md +++ b/data/reusables/repositories/review-policy-overlapping-commits.md @@ -1 +1 @@ -After all required reviewers have approved a pull request, you won't be able to merge it if there are other open pull requests with pending or rejected reviews and those pull requests have a head branch pointing to the same commit. Someone with *write* or *admin* permissions will need to approve or dismiss the blocking review on the other pull requests before you can merge. +Even after all required reviewers have approved a pull request, collaborators cannot merge the pull request if there are other open pull requests that have a head branch pointing to the same commit with pending or rejected reviews. Someone with write permissions must approve or dismiss the blocking review on the other pull requests first. diff --git a/data/reusables/repositories/squash-and-rebase-linear-commit-hisitory.md b/data/reusables/repositories/squash-and-rebase-linear-commit-hisitory.md index b74d5905b1..ba73880189 100644 --- a/data/reusables/repositories/squash-and-rebase-linear-commit-hisitory.md +++ b/data/reusables/repositories/squash-and-rebase-linear-commit-hisitory.md @@ -1 +1 @@ -{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.19" or currentVersion == "github-ae@latest" %}If there is a protected branch rule in your repository that requires a linear commit history, you must allow squash merging, rebase merging, or both. For more information, see "[Requiring a linear commit history](/github/administering-a-repository/requiring-a-linear-commit-history)."{% endif %} +{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.19" or currentVersion == "github-ae@latest" %}If there is a protected branch rule in your repository that requires a linear commit history, you must allow squash merging, rebase merging, or both. For more information, see "[About protected branches](/github/administering-a-repository/about-protected-branches#require-pull-request-reviews-before-merging)."{% endif %} diff --git a/tests/rendering/header.js b/tests/rendering/header.js index 3847ed2bf0..8cc93f5e89 100644 --- a/tests/rendering/header.js +++ b/tests/rendering/header.js @@ -21,8 +21,8 @@ describe('header', () => { describe('language links', () => { test('lead to the same page in a different language', async () => { - const $ = await getDOM('/en/github/administering-a-repository/enabling-required-status-checks') - expect($(`#languages-selector a[href="/ja/${nonEnterpriseDefaultVersion}/github/administering-a-repository/enabling-required-status-checks"]`).length).toBe(1) + const $ = await getDOM('/github/administering-a-repository/managing-a-branch-protection-rule') + expect($(`#languages-selector a[href="/ja/${nonEnterpriseDefaultVersion}/github/administering-a-repository/managing-a-branch-protection-rule"]`).length).toBe(1) }) test('display the native name and the English name for each translated language', async () => { @@ -80,7 +80,7 @@ describe('header', () => { }) test('point to homepages in the current page\'s language', async () => { - const $ = await getDOM('/ja/articles/enabling-required-status-checks') + const $ = await getDOM('/ja/github/administering-a-repository/defining-the-mergeability-of-pull-requests') expect($(`#homepages a.active[href="/ja/${nonEnterpriseDefaultVersion}/github"]`).length).toBe(1) expect($(`#homepages a[href="/ja/enterprise-server@${latest}/admin"]`).length).toBe(1) From b3a2ea4762fe3f8aea094734acdf6ecdf1ea29fc Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 11:56:01 -0500 Subject: [PATCH 45/65] update README with info about the removal of free-pro-team from URLs --- content/README.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/content/README.md b/content/README.md index 71f39c6f2f..35703a215a 100644 --- a/content/README.md +++ b/content/README.md @@ -24,6 +24,7 @@ See the [contributing docs](/CONTRIBUTING.md) for general information about work - [Escaping single quotes](#escaping-single-quotes) - [Autogenerated mini TOCs](#autogenerated-mini-tocs) - [Versioning](#versioning) + - [Free-pro-team vs. GitHub.com versioning](#free-pro-team-vs.-github.com-versioning) - [Filenames](#filenames) - [Whitespace control](#whitespace-control) - [Links and image paths](#links-and-image-paths) @@ -213,6 +214,12 @@ A content file can have **two** types of versioning: * Liquid statements in content (**optional**) * Conditionally render content depending on the current version being viewed. See [contributing/liquid-helpers](../contributing/liquid-helpers.md) for more info. Note Liquid conditionals can also appear in `data` and `include` files. +### Free-pro-team vs. GitHub.com versioning + +As of early 2021, the `free-pro-team@latest` version is **only** supported in content files (in both frontmatter and Liquid versioning) and throughout the docs site backend. It is **not** user facing. A helper function called `lib/remove-fpt-from-path.js` removes the version from URLs. Users now select `GitHub.com` in the Article Versions dropdown instead of `Free, Pro, Team`. + +The convenience function allows us to continue supporting a consistent versioning structure under-the-hood while not displaying plan information to users that may be potentially confusing. + ## Filenames When adding a new article, make sure the filename is a [kebab-cased](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles) version of the title you use in the article's [`title`](#title) frontmatter. This can get tricky when a title has punctuation (such as "GitHub's Billing Plans"). A test will flag any discrepancies between title and filename. To override this requirement for a given article, you can add [`allowTitleToDifferFromFilename`](#allowtitletodifferfromfilename) frontmatter. @@ -224,7 +231,7 @@ When using Liquid conditionals in lists or tables, you can use [whitespace contr Just add a hyphen on either the left, right, or both sides to indicate that there should be no newline on that side. For example, this statement removes a newline on the left side: ``` -{%- if page.version == 'dotcom' %} +{%- if currentVersion == 'free-pro-team@latest' %} ``` These characters are especially important in [index pages](#index-pages) comprised of list items. @@ -238,9 +245,9 @@ For example, if you include the following link in a content file: ``` /github/writing-on-github/creating-a-saved-reply ``` -When viewed on GitHub.com docs, the link gets rendered with the language code and version: +When viewed on GitHub.com docs, the link gets rendered with the language code: ``` -/en/free-pro-team@latest/github/writing-on-github/creating-a-saved-reply +/en/github/writing-on-github/creating-a-saved-reply ``` and when viewed on GitHub Enterprise Server docs, the version is included as well: ``` From af41e4ad05454a3f9461637347787f9ca618f509 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 11:56:10 -0500 Subject: [PATCH 46/65] update contributing docs --- contributing/development.md | 2 +- contributing/permalinks.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contributing/development.md b/contributing/development.md index 439e75d8c5..3187272a29 100644 --- a/contributing/development.md +++ b/contributing/development.md @@ -48,7 +48,7 @@ For more detailed instructions, please see this [VS Code recipe](https://github. While running the local server, you can visit [localhost:4000/dev-toc](http://localhost:4000/dev-toc) to view a top-level TOC of all the content in the site. This page is not available on https://docs.github.com. It was created for internal GitHub writers' use. -At the `/dev-toc` path, you'll see a list of available versions. Click a version, and a list of products will appear. Note that the TOC content is versioned. If you are viewing `free-pro-team@latest` and you click the `Enterprise Admin` product, it will be empty, because there isn't any Admin content available on that version. +At the `/dev-toc` path, you'll see a list of available versions. Click a version, and a list of products will appear. Note that the TOC content is versioned. If you are viewing the `GitHub.com` version and you click the `Enterprise Admin` product, it will be empty, because there isn't any Admin content available on that version. ## Site structure diff --git a/contributing/permalinks.md b/contributing/permalinks.md index f4c1a8532d..634990eb23 100644 --- a/contributing/permalinks.md +++ b/contributing/permalinks.md @@ -4,7 +4,7 @@ Because the site is dynamic, it does not build HTML files for each different ver For example, an article that is available in currently supported versions will have permalink URLs like the following: -* `/en/free-pro-team@latest/github/getting-started-with-github/set-up-git` +* `/en/github/getting-started-with-github/set-up-git` * `/en/enterprise-server@2.22/github/getting-started-with-github/set-up-git` * `/en/enterprise-server@2.21/github/getting-started-with-github/set-up-git` * `/en/enterprise-server@2.20/github/getting-started-with-github/set-up-git` @@ -12,7 +12,7 @@ For example, an article that is available in currently supported versions will h An article that is not available in Enterprise will have just one permalink: -* `/en/free-pro-team@latest/github/getting-started-with-github/set-up-git` +* `/en/github/getting-started-with-github/set-up-git` **If you are a content contributor:** You don't need to worry about supported versions when adding a link to a document. Following the examples above, if you want to reference an article you can just use its relative location: From 30f95ce3d2d989fe94a8707cc37096ac1295c553 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 11:56:51 -0500 Subject: [PATCH 47/65] lint --- tests/rendering/header.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/rendering/header.js b/tests/rendering/header.js index 96f3137cf4..bb11056880 100644 --- a/tests/rendering/header.js +++ b/tests/rendering/header.js @@ -21,7 +21,7 @@ describe('header', () => { describe('language links', () => { test('lead to the same page in a different language', async () => { const $ = await getDOM('/github/administering-a-repository/managing-a-branch-protection-rule') - expect($(`#languages-selector a[href="/ja/github/administering-a-repository/managing-a-branch-protection-rule"]`).length).toBe(1) + expect($('#languages-selector a[href="/ja/github/administering-a-repository/managing-a-branch-protection-rule"]').length).toBe(1) }) test('display the native name and the English name for each translated language', async () => { From 1713a29de95066964988b5b00e2dccbfe8322754 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 12:05:16 -0500 Subject: [PATCH 48/65] remove no longer relevant info --- contributing/permalinks.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/contributing/permalinks.md b/contributing/permalinks.md index 634990eb23..71d2edc456 100644 --- a/contributing/permalinks.md +++ b/contributing/permalinks.md @@ -16,6 +16,4 @@ An article that is not available in Enterprise will have just one permalink: **If you are a content contributor:** You don't need to worry about supported versions when adding a link to a document. Following the examples above, if you want to reference an article you can just use its relative location: -* `/github/getting-started-with-github/set-up-git` - -*(Please note that using a hard-coded link or supported version will result in an error when your submitted PR is automatically tested)* +* `/github/getting-started-with-github/set-up-git` \ No newline at end of file From 325c71d94eae136ca76febbf2cac2f79e8466631 Mon Sep 17 00:00:00 2001 From: "James M. Greene" Date: Fri, 15 Jan 2021 12:59:25 -0600 Subject: [PATCH 49/65] Disable the Actions workflow linter on push/PRs for now (#17330) --- .github/workflows/workflow-lint.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/workflow-lint.yml b/.github/workflows/workflow-lint.yml index 1939cad782..2b7e11429f 100644 --- a/.github/workflows/workflow-lint.yml +++ b/.github/workflows/workflow-lint.yml @@ -2,12 +2,12 @@ name: Lint workflows on: workflow_dispatch: - push: - branches: - - main - pull_request: - branches-ignore: - - translations + # push: + # branches: + # - main + # pull_request: + # branches-ignore: + # - translations jobs: lint: From ba661d65b71ba01d2a7bf4db2d7e04dc23484062 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Fri, 15 Jan 2021 15:32:23 -0500 Subject: [PATCH 50/65] do not create this redirect for deprecated enterprise versions --- lib/redirects/get-old-paths-from-permalink.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/redirects/get-old-paths-from-permalink.js b/lib/redirects/get-old-paths-from-permalink.js index df24db43b7..acc5fab624 100644 --- a/lib/redirects/get-old-paths-from-permalink.js +++ b/lib/redirects/get-old-paths-from-permalink.js @@ -1,4 +1,4 @@ -const { latest, lastReleaseWithLegacyFormat } = require('../enterprise-server-releases') +const { latest, deprecated, lastReleaseWithLegacyFormat } = require('../enterprise-server-releases') const { getPathWithoutLanguage, getPathWithLanguage, getVersionStringFromPath } = require('../path-utils') const patterns = require('../patterns') const versionSatisfiesRange = require('../version-satisfies-range') @@ -15,7 +15,7 @@ module.exports = function getOldPathsFromPath (currentPath, languageCode, curren // This only applies to Dotcom paths, so no need to determine whether the version is deprecated // create old path /free-pro-team@latest/github from new path /github (or from a frontmatter `redirect_from` path like /articles) - if (versionFromPath === 'homepage' || !currentlySupportedVersions.includes(versionFromPath) || (versionFromPath === nonEnterpriseDefaultVersion && !currentPath.includes(nonEnterpriseDefaultVersion))) { + if (versionFromPath === 'homepage' || !(currentlySupportedVersions.includes(versionFromPath) || deprecated.includes(versionFromPath)) || (versionFromPath === nonEnterpriseDefaultVersion && !currentPath.includes(nonEnterpriseDefaultVersion))) { oldPaths.add(currentPath .replace(`/${languageCode}`, `/${languageCode}/${nonEnterpriseDefaultVersion}`)) } From 871d886c16c6f50ef8223e7c767dd680f23047b2 Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Fri, 15 Jan 2021 13:16:59 -0800 Subject: [PATCH 51/65] Fail workflow when pr includes unallowed contributions (#17333) --- .github/workflows/triage-unallowed-contributions.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/triage-unallowed-contributions.yml b/.github/workflows/triage-unallowed-contributions.yml index 83cb24b5ec..662d1f19a1 100644 --- a/.github/workflows/triage-unallowed-contributions.yml +++ b/.github/workflows/triage-unallowed-contributions.yml @@ -104,6 +104,7 @@ jobs: body: reviewMessage, event: 'REQUEST_CHANGES' }) + exit 1 # prevents further steps from running and fails workflow # When the most recent review was CHANGES_REQUESTED and the existing # PR no longer contains unallowed changes, dismiss the previous review - name: Dismiss pull request review From 58aae970cf2f254beb159b2b377bca0a3f9aaeba Mon Sep 17 00:00:00 2001 From: Rachael Sewell Date: Sat, 16 Jan 2021 16:35:10 -0800 Subject: [PATCH 52/65] add troubleshooting message to openapi script (#17253) * add troubleshooting message to openapi script * i always forget to lint --- script/rest/update-files.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/script/rest/update-files.js b/script/rest/update-files.js index 38e8856006..c52ec99610 100755 --- a/script/rest/update-files.js +++ b/script/rest/update-files.js @@ -35,7 +35,7 @@ async function main () { process.exit(1) } - getDereferencedFiles() + await getDereferencedFiles() } await decorate() @@ -58,7 +58,13 @@ async function getDereferencedFiles () { mkdirp(tempDocsDir) console.log(`\n🏃‍♀️🏃🏃‍♀️Running \`bin/openapi bundle\` in branch '${githubBranch}' of your github/github checkout to generate the dereferenced OpenAPI schema files.\n`) - execSync(`${path.join(githubRepoDir, 'bin/openapi')} bundle ${tempDocsDir}`, { stdio: 'inherit' }) + try { + execSync(`${path.join(githubRepoDir, 'bin/openapi')} bundle ${tempDocsDir}`, { stdio: 'inherit' }) + } catch (error) { + console.error(error) + console.log('🛑 Whoops! It looks like the `bin/openapi bundle` command failed to run in your `github/github` repository checkout. To troubleshoot, ensure that your OpenAPI schema YAML is formatted correctly. A CI test runs on your `github/github` PR that flags malformed YAML. You can check the PR diff view for comments left by the openapi CI test to find and fix any formatting errors.') + process.exit(1) + } execSync(`find ${tempDocsDir} -type f -name "*deref.json" -exec mv '{}' ${dereferencedPath} ';'`) From ff13c94af755d57d914bf78f5b369b4c230741e5 Mon Sep 17 00:00:00 2001 From: HebaruSan Date: Sun, 17 Jan 2021 18:56:55 -0600 Subject: [PATCH 53/65] Fix workflow_dispatch permissions statement (#2179) --- .../managing-workflow-runs/manually-running-a-workflow.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/actions/managing-workflow-runs/manually-running-a-workflow.md b/content/actions/managing-workflow-runs/manually-running-a-workflow.md index 66e32aa574..753dda70cb 100644 --- a/content/actions/managing-workflow-runs/manually-running-a-workflow.md +++ b/content/actions/managing-workflow-runs/manually-running-a-workflow.md @@ -18,7 +18,7 @@ To run a workflow manually, the workflow must be configured to run on the `workf To trigger the `workflow_dispatch` event on {% data variables.product.prodname_dotcom %}, your workflow must be in the default branch. Follow these steps to manually trigger a workflow run. -{% data reusables.repositories.permissions-statement-read %} +{% data reusables.repositories.permissions-statement-write %} {% data reusables.repositories.navigate-to-repo %} {% data reusables.repositories.actions-tab %} From 251d79c39cfd24b59e322caf7a74ad07ce3d57ce Mon Sep 17 00:00:00 2001 From: DJ Adams Date: Mon, 18 Jan 2021 05:02:46 +0000 Subject: [PATCH 54/65] Include 'shell command' as a possible step task (#2211) Co-authored-by: Lucas Costi --- .../learn-github-actions/introduction-to-github-actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/actions/learn-github-actions/introduction-to-github-actions.md b/content/actions/learn-github-actions/introduction-to-github-actions.md index c84f11c6b4..3d56d7db0c 100644 --- a/content/actions/learn-github-actions/introduction-to-github-actions.md +++ b/content/actions/learn-github-actions/introduction-to-github-actions.md @@ -147,7 +147,7 @@ To help you understand how YAML syntax is used to create a workflow file, this s ``` - Groups together all the steps that run in the check-bats-version job. Each line nested under this section is a separate action. + Groups together all the steps that run in the check-bats-version job. Each item nested under this section is a separate action or shell command. From 8a4007dfd0cffafa0ea4362349a450e68ff3a435 Mon Sep 17 00:00:00 2001 From: Logan Kilpatrick <23kilpatrick23@gmail.com> Date: Sun, 17 Jan 2021 21:34:59 -0800 Subject: [PATCH 55/65] Update workflow-syntax-for-github-actions.md (#2353) --- content/actions/reference/workflow-syntax-for-github-actions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/actions/reference/workflow-syntax-for-github-actions.md b/content/actions/reference/workflow-syntax-for-github-actions.md index 1ebfc4e8d5..4030b05950 100644 --- a/content/actions/reference/workflow-syntax-for-github-actions.md +++ b/content/actions/reference/workflow-syntax-for-github-actions.md @@ -705,7 +705,7 @@ You can set the `shell` value to a template string using `command […options] { For built-in shell keywords, we provide the following defaults that are executed by {% data variables.product.prodname_dotcom %}-hosted runners. You should use these guidelines when running shell scripts. - `bash`/`sh`: - - Fail-fast behavior using `set -e o pipefail`: Default for `bash` and built-in `shell`. It is also the default when you don't provide an option on non-Windows platforms. + - Fail-fast behavior using `set -eo pipefail`: Default for `bash` and built-in `shell`. It is also the default when you don't provide an option on non-Windows platforms. - You can opt out of fail-fast and take full control by providing a template string to the shell options. For example, `bash {0}`. - sh-like shells exit with the exit code of the last command executed in a script, which is also the default behavior for actions. The runner will report the status of the step as fail/succeed based on this exit code. From 9a07d5a491e89377214122b62082d421218e9ab0 Mon Sep 17 00:00:00 2001 From: Simran Date: Mon, 18 Jan 2021 08:19:38 +0100 Subject: [PATCH 56/65] Actions: Various fixes for migration pages (#2093) --- ...-from-azure-pipelines-to-github-actions.md | 148 ++++++------ ...grating-from-circleci-to-github-actions.md | 78 +++---- ...ting-from-gitlab-cicd-to-github-actions.md | 38 ++-- ...igrating-from-jenkins-to-github-actions.md | 211 +++++++++--------- ...rating-from-travis-ci-to-github-actions.md | 71 +++--- stylesheets/tables.scss | 7 + 6 files changed, 277 insertions(+), 276 deletions(-) diff --git a/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md index d80d7fb120..42d8fe4c79 100644 --- a/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-azure-pipelines-to-github-actions.md @@ -62,16 +62,16 @@ Azure Pipelines {% raw %} ```yaml jobs: -- job: scripts - pool: - vmImage: 'windows-latest' - steps: - - script: echo "This step runs in the default shell" - - bash: echo "This step runs in bash" - - pwsh: Write-Host "This step runs in PowerShell Core" - - task: PowerShell@2 - inputs: - script: Write-Host "This step runs in PowerShell" + - job: scripts + pool: + vmImage: 'windows-latest' + steps: + - script: echo "This step runs in the default shell" + - bash: echo "This step runs in bash" + - pwsh: Write-Host "This step runs in PowerShell Core" + - task: PowerShell@2 + inputs: + script: Write-Host "This step runs in PowerShell" ``` {% endraw %} @@ -82,13 +82,13 @@ jobs: scripts: runs-on: windows-latest steps: - - run: echo "This step runs in the default shell" - - run: echo "This step runs in bash" - shell: bash - - run: Write-Host "This step runs in PowerShell Core" - shell: pwsh - - run: Write-Host "This step runs in PowerShell" - shell: powershell + - run: echo "This step runs in the default shell" + - run: echo "This step runs in bash" + shell: bash + - run: Write-Host "This step runs in PowerShell Core" + shell: pwsh + - run: Write-Host "This step runs in PowerShell" + shell: powershell ``` {% endraw %} @@ -123,11 +123,11 @@ Azure Pipelines {% raw %} ```yaml jobs: -- job: run_command - pool: - vmImage: 'windows-latest' - steps: - - script: echo "This step runs in CMD on Windows by default" + - job: run_command + pool: + vmImage: 'windows-latest' + steps: + - script: echo "This step runs in CMD on Windows by default" ``` {% endraw %} @@ -138,9 +138,9 @@ jobs: run_command: runs-on: windows-latest steps: - - run: echo "This step runs in PowerShell on Windows by default" - - run: echo "This step runs in CMD on Windows explicitly" - shell: cmd + - run: echo "This step runs in PowerShell on Windows by default" + - run: echo "This step runs in CMD on Windows explicitly" + shell: cmd ``` {% endraw %} @@ -171,12 +171,12 @@ Azure Pipelines {% raw %} ```yaml jobs: -- job: conditional - pool: - vmImage: 'ubuntu-latest' - steps: - - script: echo "This step runs with str equals 'ABC' and num equals 123" - condition: and(eq(variables.str, 'ABC'), eq(variables.num, 123)) + - job: conditional + pool: + vmImage: 'ubuntu-latest' + steps: + - script: echo "This step runs with str equals 'ABC' and num equals 123" + condition: and(eq(variables.str, 'ABC'), eq(variables.num, 123)) ``` {% endraw %} @@ -187,8 +187,8 @@ jobs: conditional: runs-on: ubuntu-latest steps: - - run: echo "This step runs with str equals 'ABC' and num equals 123" - if: ${{ env.str == 'ABC' && env.num == 123 }} + - run: echo "This step runs with str equals 'ABC' and num equals 123" + if: ${{ env.str == 'ABC' && env.num == 123 }} ``` {% endraw %} @@ -217,29 +217,29 @@ Azure Pipelines {% raw %} ```yaml jobs: -- job: initial - pool: - vmImage: 'ubuntu-latest' - steps: - - script: echo "This job will be run first." -- job: fanout1 - pool: - vmImage: 'ubuntu-latest' - dependsOn: initial - steps: - - script: echo "This job will run after the initial job, in parallel with fanout2." -- job: fanout2 - pool: - vmImage: 'ubuntu-latest' - dependsOn: initial - steps: - - script: echo "This job will run after the initial job, in parallel with fanout1." -- job: fanin: - pool: - vmImage: 'ubuntu-latest' - dependsOn: [fanout1, fanout2] - steps: - - script: echo "This job will run after fanout1 and fanout2 have finished." + - job: initial + pool: + vmImage: 'ubuntu-latest' + steps: + - script: echo "This job will be run first." + - job: fanout1 + pool: + vmImage: 'ubuntu-latest' + dependsOn: initial + steps: + - script: echo "This job will run after the initial job, in parallel with fanout2." + - job: fanout2 + pool: + vmImage: 'ubuntu-latest' + dependsOn: initial + steps: + - script: echo "This job will run after the initial job, in parallel with fanout1." + - job: fanin: + pool: + vmImage: 'ubuntu-latest' + dependsOn: [fanout1, fanout2] + steps: + - script: echo "This job will run after fanout1 and fanout2 have finished." ``` {% endraw %} @@ -250,22 +250,22 @@ jobs: initial: runs-on: ubuntu-latest steps: - - run: echo "This job will be run first." + - run: echo "This job will be run first." fanout1: runs-on: ubuntu-latest needs: initial steps: - - run: echo "This job will run after the initial job, in parallel with fanout2." + - run: echo "This job will run after the initial job, in parallel with fanout2." fanout2: runs-on: ubuntu-latest needs: initial steps: - - run: echo "This job will run after the initial job, in parallel with fanout1." + - run: echo "This job will run after the initial job, in parallel with fanout1." fanin: runs-on: ubuntu-latest needs: [fanout1, fanout2] steps: - - run: echo "This job will run after fanout1 and fanout2 have finished." + - run: echo "This job will run after fanout1 and fanout2 have finished." ``` {% endraw %} @@ -294,15 +294,15 @@ Azure Pipelines {% raw %} ```yaml jobs: -- job: run_python - pool: - vmImage: 'ubuntu-latest' - steps: - - task: UsePythonVersion@0 - inputs: - versionSpec: '3.7' - architecture: 'x64' - - script: python script.py + - job: run_python + pool: + vmImage: 'ubuntu-latest' + steps: + - task: UsePythonVersion@0 + inputs: + versionSpec: '3.7' + architecture: 'x64' + - script: python script.py ``` {% endraw %} @@ -313,11 +313,11 @@ jobs: run_python: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2 - with: - python-version: '3.7' - architecture: 'x64' - - run: python script.py + - uses: actions/setup-python@v2 + with: + python-version: '3.7' + architecture: 'x64' + - run: python script.py ``` {% endraw %} diff --git a/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md index 8dae1c3e25..58502218ca 100644 --- a/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-circleci-to-github-actions.md @@ -258,24 +258,24 @@ jobs: POSTGRES_DB: ruby25 POSTGRES_PASSWORD: "" ports: - - 5432:5432 + - 5432:5432 # Add a health check options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - # This Docker file changes sets USER to circleci instead of using the default user, so we need to update file permissions for this image to work on GH Actions. - # See https://docs.github.com/actions/reference/virtual-environments-for-github-hosted-runners#docker-container-filesystem - - name: Setup file system permissions - run: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp - - uses: actions/checkout@v2 - - name: Install dependencies - run: bundle install --path vendor/bundle - - name: Setup environment configuration - run: cp .sample.env .env - - name: Setup database - run: bundle exec rake db:setup - - name: Run tests - run: bundle exec rake + # This Docker file changes sets USER to circleci instead of using the default user, so we need to update file permissions for this image to work on GH Actions. + # See https://docs.github.com/actions/reference/virtual-environments-for-github-hosted-runners#docker-container-filesystem + - name: Setup file system permissions + run: sudo chmod -R 777 $GITHUB_WORKSPACE /github /__w/_temp + - uses: actions/checkout@v2 + - name: Install dependencies + run: bundle install --path vendor/bundle + - name: Setup environment configuration + run: cp .sample.env .env + - name: Setup database + run: bundle exec rake db:setup + - name: Run tests + run: bundle exec rake ``` {% endraw %} @@ -412,35 +412,35 @@ jobs: POSTGRES_DB: ruby25 POSTGRES_PASSWORD: "" ports: - - 5432:5432 + - 5432:5432 # Add a health check options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5 steps: - - uses: actions/checkout@v2 - - name: Setup Ruby - uses: eregon/use-ruby-action@master - with: - ruby-version: ${{ matrix.ruby }} - - name: Cache dependencies - uses: actions/cache@v2 - with: - path: vendor/bundle - key: administrate-${{ matrix.image }}-${{ hashFiles('Gemfile.lock') }} - - name: Install postgres headers - run: sudo apt-get install libpq-dev - - name: Install dependencies - run: bundle install --path vendor/bundle - - name: Setup environment configuration - run: cp .sample.env .env - - name: Setup database - run: bundle exec rake db:setup - - name: Run tests - run: bundle exec rake - - name: Install appraisal - run: bundle exec appraisal install - - name: Run appraisal - run: bundle exec appraisal rake + - uses: actions/checkout@v2 + - name: Setup Ruby + uses: eregon/use-ruby-action@master + with: + ruby-version: ${{ matrix.ruby }} + - name: Cache dependencies + uses: actions/cache@v2 + with: + path: vendor/bundle + key: administrate-${{ matrix.image }}-${{ hashFiles('Gemfile.lock') }} + - name: Install postgres headers + run: sudo apt-get install libpq-dev + - name: Install dependencies + run: bundle install --path vendor/bundle + - name: Setup environment configuration + run: cp .sample.env .env + - name: Setup database + run: bundle exec rake db:setup + - name: Run tests + run: bundle exec rake + - name: Install appraisal + run: bundle exec appraisal install + - name: Run appraisal + run: bundle exec appraisal rake ``` {% endraw %} diff --git a/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md index 4fa6ce3d64..2af0aafcfc 100644 --- a/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-gitlab-cicd-to-github-actions.md @@ -60,8 +60,8 @@ job1: jobs: job1: steps: - - uses: actions/checkout@v2 - - run: echo "Run your script here" + - uses: actions/checkout@v2 + - run: echo "Run your script here" ``` {% endraw %} @@ -257,24 +257,24 @@ jobs: build_a: runs-on: ubuntu-latest steps: - - run: echo "This job will be run first." + - run: echo "This job will be run first." build_b: runs-on: ubuntu-latest steps: - - run: echo "This job will be run first, in parallel with build_a" + - run: echo "This job will be run first, in parallel with build_a" test_ab: runs-on: ubuntu-latest needs: [build_a,build_b] steps: - - run: echo "This job will run after build_a and build_b have finished" + - run: echo "This job will run after build_a and build_b have finished" deploy_ab: runs-on: ubuntu-latest needs: [test_ab] steps: - - run: echo "This job will run after test_ab is complete" + - run: echo "This job will run after test_ab is complete" ``` {% endraw %} @@ -335,12 +335,12 @@ test_async: ```yaml jobs: test_async: - - name: Cache node modules - uses: actions/cache@v2 - with: - path: ~/.npm - key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }} - restore-keys: v1-npm-deps- + - name: Cache node modules + uses: actions/cache@v2 + with: + path: ~/.npm + key: v1-npm-deps-${{ hashFiles('**/package-lock.json') }} + restore-keys: v1-npm-deps- ``` {% endraw %} @@ -371,7 +371,7 @@ GitLab CI/CD script: artifacts: paths: - - math-homework.txt + - math-homework.txt ``` {% endraw %} @@ -424,12 +424,12 @@ container-job: services: - postgres script: - # Performs a clean installation of all dependencies - # in the `package.json` file - - npm ci - # Runs a script that creates a PostgreSQL client, - # populates the client with data, and retrieves data - - node client.js + # Performs a clean installation of all dependencies + # in the `package.json` file + - npm ci + # Runs a script that creates a PostgreSQL client, + # populates the client with data, and retrieves data + - node client.js tags: - docker ``` diff --git a/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md index 0bcf0df3de..0a036cc76f 100644 --- a/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-jenkins-to-github-actions.md @@ -36,21 +36,20 @@ Jenkins lets you send builds to a single build agent, or you can distribute them Similarly, {% data variables.product.prodname_actions %} can send jobs to {% data variables.product.prodname_dotcom %}-hosted or self-hosted runners, and you can use labels to classify runners according to various attributes. The following table compares how the distributed build concept is implemented for both Jenkins and {% data variables.product.prodname_actions %}. -| Jenkins | {% data variables.product.prodname_actions %} | +| Jenkins | {% data variables.product.prodname_actions %} | | ------------- | ------------- | -| [`agents`](https://wiki.jenkins.io/display/JENKINS/Distributed+builds) | [`runners`](/actions/learn-github-actions/introduction-to-github-actions#runners)
    [`self-hosted runners`](/actions/hosting-your-own-runners/about-self-hosted-runners)| +| [`agents`](https://wiki.jenkins.io/display/JENKINS/Distributed+builds) | [`runners`](/actions/learn-github-actions/introduction-to-github-actions#runners)
    [`self-hosted runners`](/actions/hosting-your-own-runners/about-self-hosted-runners) | #### Using sections to organize pipelines Jenkins splits its Declarative Pipelines into multiple sections. Similarly, {% data variables.product.prodname_actions %} organizes its workflows into separate sections. The table below compares Jenkins sections with the {% data variables.product.prodname_actions %} workflow. -|Jenkins Directives | {% data variables.product.prodname_actions %} | +| Jenkins Directives | {% data variables.product.prodname_actions %} | | ------------- | ------------- | -| [`agent`](https://jenkins.io/doc/book/pipeline/syntax/#agent) | [`jobs..runs-on`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idruns-on)
    [`jobs..container`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idcontainer)| -| [`post`](https://jenkins.io/doc/book/pipeline/syntax/#post) | | -| [`stages`](https://jenkins.io/doc/book/pipeline/syntax/#stages) | [`jobs`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobs) | -| [`steps`](https://jenkins.io/doc/book/pipeline/syntax/#steps) | [`jobs..steps`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idsteps) | - +| [`agent`](https://jenkins.io/doc/book/pipeline/syntax/#agent) | [`jobs..runs-on`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idruns-on)
    [`jobs..container`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idcontainer) | +| [`post`](https://jenkins.io/doc/book/pipeline/syntax/#post) | | +| [`stages`](https://jenkins.io/doc/book/pipeline/syntax/#stages) | [`jobs`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobs) | +| [`steps`](https://jenkins.io/doc/book/pipeline/syntax/#steps) | [`jobs..steps`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idsteps) | ### Using directives @@ -58,17 +57,16 @@ Jenkins uses directives to manage _Declarative Pipelines_. These directives defi | Jenkins Directives | {% data variables.product.prodname_actions %} | | ------------- | ------------- | -| [`environment`](https://jenkins.io/doc/book/pipeline/syntax/#environment) | [`jobs..env`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#env)
    [`jobs..steps[*].env`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsenv) | -| [`options`](https://jenkins.io/doc/book/pipeline/syntax/#parameters) | [`jobs..strategy`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategy)
    [`jobs..strategy.fail-fast`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast)
    [`jobs..timeout-minutes`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes)| -| [`parameters`](https://jenkins.io/doc/book/pipeline/syntax/#parameters) | [`inputs`](/actions/creating-actions/metadata-syntax-for-github-actions#inputs)
    [`outputs`](/actions/creating-actions/metadata-syntax-for-github-actions#outputs) | -| [`triggers`](https://jenkins.io/doc/book/pipeline/syntax/#triggers) | [`on`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#on)
    [`on..types`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onevent_nametypes)
    [on..](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags)
    [on..paths](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onpushpull_requestpaths) | -| [`triggers { upstreamprojects() }`](https://jenkins.io/doc/book/pipeline/syntax/#triggers) | [`jobs..needs`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idneeds) | -| [Jenkins cron syntax](https://jenkins.io/doc/book/pipeline/syntax/#cron-syntax) | [`on.schedule`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onschedule) | -| [`stage`](https://jenkins.io/doc/book/pipeline/syntax/#stage) | [`jobs.`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_id)
    [`jobs..name`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idname)| -| [`tools`](https://jenkins.io/doc/book/pipeline/syntax/#tools) | [Specifications for {% data variables.product.prodname_dotcom %}-hosted runners](/actions/reference/specifications-for-github-hosted-runners/#supported-software) | -| [`input`](https://jenkins.io/doc/book/pipeline/syntax/#input) | [`inputs`](/actions/automating-your-workflow-with-github-actions/metadata-syntax-for-github-actions#inputs) | -| [`when`](https://jenkins.io/doc/book/pipeline/syntax/#when) | [`jobs..if`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idif) | - +| [`environment`](https://jenkins.io/doc/book/pipeline/syntax/#environment) | [`jobs..env`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#env)
    [`jobs..steps[*].env`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstepsenv) | +| [`options`](https://jenkins.io/doc/book/pipeline/syntax/#parameters) | [`jobs..strategy`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategy)
    [`jobs..strategy.fail-fast`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idstrategyfail-fast)
    [`jobs..timeout-minutes`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idtimeout-minutes) | +| [`parameters`](https://jenkins.io/doc/book/pipeline/syntax/#parameters) | [`inputs`](/actions/creating-actions/metadata-syntax-for-github-actions#inputs)
    [`outputs`](/actions/creating-actions/metadata-syntax-for-github-actions#outputs) | +| [`triggers`](https://jenkins.io/doc/book/pipeline/syntax/#triggers) | [`on`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#on)
    [`on..types`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onevent_nametypes)
    [on..](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onpushpull_requestbranchestags)
    [on..paths](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onpushpull_requestpaths) | +| [`triggers { upstreamprojects() }`](https://jenkins.io/doc/book/pipeline/syntax/#triggers) | [`jobs..needs`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idneeds) | +| [Jenkins cron syntax](https://jenkins.io/doc/book/pipeline/syntax/#cron-syntax) | [`on.schedule`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#onschedule) | +| [`stage`](https://jenkins.io/doc/book/pipeline/syntax/#stage) | [`jobs.`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_id)
    [`jobs..name`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idname) | +| [`tools`](https://jenkins.io/doc/book/pipeline/syntax/#tools) | [Specifications for {% data variables.product.prodname_dotcom %}-hosted runners](/actions/reference/specifications-for-github-hosted-runners/#supported-software) | +| [`input`](https://jenkins.io/doc/book/pipeline/syntax/#input) | [`inputs`](/actions/automating-your-workflow-with-github-actions/metadata-syntax-for-github-actions#inputs) | +| [`when`](https://jenkins.io/doc/book/pipeline/syntax/#when) | [`jobs..if`](/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#jobsjob_idif) | ### Using sequential stages @@ -84,19 +82,19 @@ Jenkins can run the `stages` and `steps` in parallel, while {% data variables.pr Both {% data variables.product.prodname_actions %} and Jenkins let you use a build matrix to define various system combinations. -| Jenkins | {% data variables.product.prodname_actions %} | +| Jenkins | {% data variables.product.prodname_actions %} | | ------------- | ------------- | -| [`axis`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-axes) | [`strategy/matrix`](/actions/learn-github-actions/managing-complex-workflows/#using-a-build-matrix)
    [`context`](/actions/reference/context-and-expression-syntax-for-github-actions) | -| [`stages`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-stages) | [`steps-context`](/actions/reference/context-and-expression-syntax-for-github-actions#steps-context) | -| [`excludes`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-stages) | | +| [`axis`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-axes) | [`strategy/matrix`](/actions/learn-github-actions/managing-complex-workflows/#using-a-build-matrix)
    [`context`](/actions/reference/context-and-expression-syntax-for-github-actions) | +| [`stages`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-stages) | [`steps-context`](/actions/reference/context-and-expression-syntax-for-github-actions#steps-context) | +| [`excludes`](https://jenkins.io/doc/book/pipeline/syntax/#matrix-stages) | | #### Using steps to execute tasks Jenkins groups `steps` together in `stages`. Each of these steps can be a script, function, or command, among others. Similarly, {% data variables.product.prodname_actions %} uses `jobs` to execute specific groups of `steps`. -| Jenkins steps | {% data variables.product.prodname_actions %} | +| Jenkins steps | {% data variables.product.prodname_actions %} | | ------------- | ------------- | -| [`script`](https://jenkins.io/doc/book/pipeline/syntax/#script) | [`jobs..steps`](/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps) | +| [`script`](https://jenkins.io/doc/book/pipeline/syntax/#script) | [`jobs..steps`](/actions/reference/workflow-syntax-for-github-actions#jobsjob_idsteps) | ### Examples of common tasks @@ -114,23 +112,23 @@ Jenkins Pipeline - ```yaml - pipeline { - agent any - triggers { - cron('H/15 * * * 1-5') - } - } - ``` +```yaml +pipeline { + agent any + triggers { + cron('H/15 * * * 1-5') + } +} +``` - ```yaml - on: +```yaml +on: schedule: - - cron: '*/15 * * * 1-5' - ``` + - cron: '*/15 * * * 1-5' +``` @@ -150,25 +148,24 @@ Jenkins Pipeline - ```yaml - pipeline { - agent any - environment { - MAVEN_PATH = '/usr/local/maven' - } +```yaml +pipeline { + agent any + environment { + MAVEN_PATH = '/usr/local/maven' } - ``` +} +``` - ```yaml - jobs: - maven-build: +```yaml +jobs: + maven-build: env: MAVEN_PATH: '/usr/local/maven' - - ``` +``` @@ -188,30 +185,28 @@ Jenkins Pipeline - ```yaml - pipeline { - triggers { - upstream( - upstreamProjects: 'job1,job2', - threshold: hudson.model.Result.SUCCESS) - } - } +```yaml +pipeline { + triggers { + upstream( + upstreamProjects: 'job1,job2', + threshold: hudson.model.Result.SUCCESS + ) } - - ``` +} +``` - ```yaml - jobs: - job1: - job2: - needs: job1 - job3: - needs: [job1, job2] - - ``` +```yaml +jobs: + job1: + job2: + needs: job1 + job3: + needs: [job1, job2] +``` @@ -231,26 +226,27 @@ Jenkins Pipeline - ```yaml +```yaml pipeline { -agent none -stages { - stage('Run Tests') { - matrix { - axes { - axis { - name: 'PLATFORM' - values: 'macos', 'linux' + agent none + stages { + stage('Run Tests') { + matrix { + axes { + axis { + name: 'PLATFORM' + values: 'macos', 'linux' + } } - } - agent { label "${PLATFORM}" } - stages { - stage('test') { - tools { nodejs "node-12" } - steps { - dir("scripts/myapp") { - sh(script: "npm install -g bats") - sh(script: "bats tests") + agent { label "${PLATFORM}" } + stages { + stage('test') { + tools { nodejs "node-12" } + steps { + dir("scripts/myapp") { + sh(script: "npm install -g bats") + sh(script: "bats tests") + } } } } @@ -258,33 +254,32 @@ stages { } } } -} - ``` +``` {% raw %} - ```yaml - name: demo-workflow - on: - push: - jobs: - test: - runs-on: ${{ matrix.os }} - strategy: - fail-fast: false - matrix: - os: [macos-latest, ubuntu-latest] - steps: - - uses: actions/checkout@v1 - - uses: actions/setup-node@v1 - with: - node-version: 12 - - run: npm install -g bats - - run: bats tests - working-directory: scripts/myapp - ``` +```yaml +name: demo-workflow +on: + push: +jobs: + test: + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false + matrix: + os: [macos-latest, ubuntu-latest] + steps: + - uses: actions/checkout@v1 + - uses: actions/setup-node@v1 + with: + node-version: 12 + - run: npm install -g bats + - run: bats tests + working-directory: scripts/myapp +``` {% endraw %} diff --git a/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md b/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md index 4eb55be554..194bf41107 100644 --- a/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md +++ b/content/actions/learn-github-actions/migrating-from-travis-ci-to-github-actions.md @@ -70,8 +70,8 @@ Travis CI ```yaml matrix: include: - - rvm: 2.5 - - rvm: 2.6.3 + - rvm: 2.5 + - rvm: 2.6.3 ``` {% endraw %} @@ -110,8 +110,8 @@ Travis CI ```yaml branches: only: - - main - - 'mona/octocat' + - main + - 'mona/octocat' ``` {% endraw %} @@ -120,7 +120,7 @@ branches: ```yaml on: push: - branches: + branches: - main - 'mona/octocat' ``` @@ -156,9 +156,9 @@ git: {% raw %} ```yaml - - uses: actions/checkout@v2 - with: - submodules: false +- uses: actions/checkout@v2 + with: + submodules: false ``` {% endraw %} @@ -208,10 +208,10 @@ When working with different languages in {% data variables.product.prodname_acti For example: ```yaml - steps: - - name: Run build script - run: ./.github/scripts/build.sh - shell: bash +steps: + - name: Run build script + run: ./.github/scripts/build.sh + shell: bash ``` ### Error handling in {% data variables.product.prodname_actions %} @@ -276,11 +276,11 @@ jobs: run_python: runs-on: ubuntu-latest steps: - - uses: actions/setup-python@v2 - with: - python-version: '3.7' - architecture: 'x64' - - run: python script.py + - uses: actions/setup-python@v2 + with: + python-version: '3.7' + architecture: 'x64' + - run: python script.py ``` {% endraw %} @@ -346,20 +346,20 @@ Travis CI - ```yaml +```yaml env: - MAVEN_PATH="/usr/local/maven" - ``` +``` - ```yaml - jobs: - maven-build: - env: - MAVEN_PATH: '/usr/local/maven' - ``` +```yaml +jobs: + maven-build: + env: + MAVEN_PATH: '/usr/local/maven' +``` @@ -379,24 +379,24 @@ Travis CI {% raw %} - ```yaml +```yaml install: - - npm install + - npm install script: - - npm run build - - npm test - ``` + - npm run build + - npm test +``` {% endraw %} {% raw %} - ```yaml +```yaml name: Node.js CI on: [push] jobs: - build: - runs-on: ubuntu-latest - steps: + build: + runs-on: ubuntu-latest + steps: - uses: actions/checkout@v2 - name: Use Node.js uses: actions/setup-node@v1 @@ -405,13 +405,12 @@ jobs: - run: npm install - run: npm run build - run: npm test - ``` +``` {% endraw %} - ### Next steps To continue learning about the main features of {% data variables.product.prodname_actions %}, see "[Learn {% data variables.product.prodname_actions %}](/actions/learn-github-actions)." diff --git a/stylesheets/tables.scss b/stylesheets/tables.scss index 9423c9a011..1da1775983 100644 --- a/stylesheets/tables.scss +++ b/stylesheets/tables.scss @@ -16,6 +16,13 @@ border-radius: $border-radius; } + pre { + > code { + padding: 0; + background-color: transparent; + } + } + thead tr { border: none; } From 7a5c9db74782da0d442925de4b2b38c390abad57 Mon Sep 17 00:00:00 2001 From: mchammer01 <42146119+mchammer01@users.noreply.github.com> Date: Mon, 18 Jan 2021 09:07:43 +0000 Subject: [PATCH 57/65] complete updates --- .../about-github-advanced-security.md | 2 +- .../about-alerts-for-vulnerable-dependencies.md | 2 ++ ...itory-permission-levels-for-an-organization.md | 15 ++++++++++----- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/content/github/getting-started-with-github/about-github-advanced-security.md b/content/github/getting-started-with-github/about-github-advanced-security.md index 0aea22bcfd..84cae9f443 100644 --- a/content/github/getting-started-with-github/about-github-advanced-security.md +++ b/content/github/getting-started-with-github/about-github-advanced-security.md @@ -10,7 +10,7 @@ versions: {% data variables.product.prodname_dotcom %} has many features that help you improve and maintain the quality of your code. Some of these are included in all plans, for example: dependency graph and {% data variables.product.prodname_dependabot_alerts %}. Other security features require a license for {% data variables.product.prodname_GH_advanced_security %} to run on repositories apart from public repositories on {% data variables.product.prodname_dotcom_the_website %}. (That is, private and internal repositories on {% data variables.product.prodname_dotcom_the_website %}, and all repositories on {% data variables.product.prodname_ghe_server %}.) -For an overview of all security features, see "[About securing your repository](/github/administering-a-repository/about-securing-your-repository#setting-up-your-repository-securely)." +For an overview of all security features, see "[About securing your repository](/github/administering-a-repository/about-securing-your-repository#setting-up-your-repository-securely)." For information about permission requirements for actions related to security features, see "[Repository permission levels for an organization](/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization#permission-requirements-for-security-features)." ### About {% data variables.product.prodname_advanced_security %} features diff --git a/content/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies.md b/content/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies.md index 67f9613edb..1be5ca75ca 100644 --- a/content/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies.md +++ b/content/github/managing-security-vulnerabilities/about-alerts-for-vulnerable-dependencies.md @@ -47,6 +47,8 @@ For a list of the ecosystems that {% data variables.product.product_name %} can You can also enable or disable {% data variables.product.prodname_dependabot_alerts %} for all repositories owned by your user account or organization. For more information, see "[Managing security and analysis settings for your user account](/github/setting-up-and-managing-your-github-user-account/managing-security-and-analysis-settings-for-your-user-account)" or "[Managing security and analysis settings for your organization](/github/setting-up-and-managing-organizations-and-teams/managing-security-and-analysis-settings-for-your-organization)." +For information about permission requirements for actions related to {% data variables.product.prodname_dependabot_alerts %}, see "[Repository permission levels for an organization](/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization#permission-requirements-for-security-features)." + {% data variables.product.product_name %} starts generating the dependency graph immediately and generates alerts for any vulnerable dependencies as soon as they are identified. The graph is usually populated within minutes but this may take longer for repositories with many dependencies. For more information, see "[Managing data use settings for your private repository](/github/understanding-how-github-uses-and-protects-your-data/managing-data-use-settings-for-your-private-repository)." {% endif %} diff --git a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md index e8ba36def3..13b6f66adf 100644 --- a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md +++ b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md @@ -43,12 +43,13 @@ In addition to managing organization-level settings, organization owners have ad {% endwarning %} ### Repository access for each permission level - +{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} {% note %} -**Note:** Repository permissions required for security features are listed in [Permission levels for code security features](#permission-levels-for-code-security-features) below. +**Note:** Repository permissions required for actions related to security features are listed in "[Permission requirements for security features](#permission-requirements-for-security-features)" below. {% endnote %} +{% endif %} | Repository action | Read | Triage | Write | Maintain | Admin | |:---|:---:|:---:|:---:|:---:|:---:| @@ -129,7 +130,10 @@ In addition to managing organization-level settings, organization owners have ad | [Create new discussions and comment on existing discussions](/discussions/collaborating-with-your-community-using-discussions/participating-in-a-discussion) | **X** | **X** | **X** | **X** | **X** | | [Delete a discussion](/discussions/managing-discussions-for-your-community/managing-discussions-in-your-repository#deleting-a-discussion) | | | | **X** | **X** |{% endif %} -#### Permission levels for code security features +{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} +#### Permission requirements for security features + +In this section, you can find the repository permission levels required for {% data variables.product.prodname_dependabot %} and {% data variables.product.prodname_advanced_security %} features. | Repository action | Read | Triage | Write | Maintain | Admin | |:---|:---:|:---:|:---:|:---:|:---:|{% if currentVersion == "free-pro-team@latest" %} @@ -142,9 +146,10 @@ In addition to managing organization-level settings, organization owners have ad | [View dependency reviews](/github/collaborating-with-issues-and-pull-requests/reviewing-dependency-changes-in-a-pull-request) | **X** | **X** | **X** | **X** | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} | [View {% data variables.product.prodname_code_scanning %} alerts on pull requests](/github/finding-security-vulnerabilities-and-errors-in-your-code/triaging-code-scanning-alerts-in-pull-requests) | **X** | **X** | **X** | **X** | **X** | | [List, dismiss, and delete {% data variables.product.prodname_code_scanning %} alerts](/github/finding-security-vulnerabilities-and-errors-in-your-code/managing-code-scanning-alerts-for-your-repository) | | | **X** | **X** | **X** |{% endif %}{% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.22" %} -| [View {% data variables.product.prodname_secret_scanning %} alerts in a repository, and also resolve, revoke or re-open {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-alerts-from-secret-scanning) | | | | | **X** | +| [View {% data variables.product.prodname_secret_scanning %} alerts in a repository](/github/administering-a-repository/managing-alerts-from-secret-scanning) | | | | | **X** | +| [Resolve, revoke or re-open {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-alerts-from-secret-scanning) | | | | | **X** | | [Designate additional people or teams to receive {% data variables.product.prodname_secret_scanning %} alerts](/github/administering-a-repository/managing-security-and-analysis-settings-for-your-repository#granting-access-to-security-alerts) in repositories | | | | | **X** |{% endif %} - +{% endif %} ### Further reading From 198a6bd119c526f0e1270b37e0d41e0df3b9e621 Mon Sep 17 00:00:00 2001 From: github-openapi-bot <69533958+github-openapi-bot@users.noreply.github.com> Date: Mon, 18 Jan 2021 04:39:56 -0500 Subject: [PATCH 58/65] Updating OpenAPI descriptions (#17324) * Updating OpenAPI descriptions * Add decorated OpenAPI schema files Co-authored-by: Leona B. Campbell <3880403+runleonarun@users.noreply.github.com> --- lib/rest/static/decorated/api.github.com.json | 12 ++++++------ lib/rest/static/decorated/ghes-2.18.json | 8 ++++---- lib/rest/static/decorated/ghes-2.19.json | 8 ++++---- lib/rest/static/decorated/ghes-2.20.json | 8 ++++---- lib/rest/static/decorated/ghes-2.21.json | 8 ++++---- lib/rest/static/decorated/ghes-2.22.json | 8 ++++---- lib/rest/static/decorated/ghes-3.0.json | 8 ++++---- lib/rest/static/decorated/github.ae.json | 8 ++++---- .../static/dereferenced/api.github.com.deref.json | 8 ++++---- lib/rest/static/dereferenced/ghes-2.18.deref.json | 6 +++--- lib/rest/static/dereferenced/ghes-2.19.deref.json | 6 +++--- lib/rest/static/dereferenced/ghes-2.20.deref.json | 6 +++--- lib/rest/static/dereferenced/ghes-2.21.deref.json | 6 +++--- lib/rest/static/dereferenced/ghes-2.22.deref.json | 6 +++--- lib/rest/static/dereferenced/ghes-3.0.deref.json | 6 +++--- lib/rest/static/dereferenced/github.ae.deref.json | 6 +++--- 16 files changed, 59 insertions(+), 59 deletions(-) diff --git a/lib/rest/static/decorated/api.github.com.json b/lib/rest/static/decorated/api.github.com.json index df5449826b..04e165da07 100644 --- a/lib/rest/static/decorated/api.github.com.json +++ b/lib/rest/static/decorated/api.github.com.json @@ -50298,7 +50298,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://support.github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -50340,7 +50340,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Support or GitHub Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Support or GitHub Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -54341,7 +54341,7 @@ } ], "summary": "Get an import status", - "description": "View the progress of an import.\n\n**Import status**\n\nThis section includes details about the possible values of the `status` field of the Import Progress response.\n\nAn import that does not have errors will progress through these steps:\n\n* `detecting` - the \"detection\" step of the import is in progress because the request did not include a `vcs` parameter. The import is identifying the type of source control present at the URL.\n* `importing` - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include `commit_count` (the total number of raw commits that will be imported) and `percent` (0 - 100, the current progress through the import).\n* `mapping` - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.\n* `pushing` - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include `push_percent`, which is the percent value reported by `git push` when it is \"Writing objects\".\n* `complete` - the import is complete, and the repository is ready on GitHub.\n\nIf there are problems, you will see one of these in the `status` field:\n\n* `auth_failed` - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `error` - the import encountered an error. The import progress response will include the `failed_step` and an error message. Contact [GitHub Support](https://github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com) for more information.\n* `detection_needs_auth` - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `detection_found_nothing` - the importer didn't recognize any source control at the URL. To resolve, [Cancel the import](https://docs.github.com/rest/reference/migrations#cancel-an-import) and [retry](https://docs.github.com/rest/reference/migrations#start-an-import) with the correct URL.\n* `detection_found_multiple` - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a `project_choices` field with the possible project choices as values. To update project choice, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n\n**The project_choices field**\n\nWhen multiple projects are found at the provided URL, the response hash will include a `project_choices` field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.\n\n**Git LFS related fields**\n\nThis section includes details about Git LFS related fields that may be present in the Import Progress response.\n\n* `use_lfs` - describes whether the import has been opted in or out of using Git LFS. The value can be `opt_in`, `opt_out`, or `undecided` if no action has been taken.\n* `has_large_files` - the boolean value describing whether files larger than 100MB were found during the `importing` step.\n* `large_files_size` - the total size in gigabytes of files larger than 100MB found in the originating repository.\n* `large_files_count` - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.", + "description": "View the progress of an import.\n\n**Import status**\n\nThis section includes details about the possible values of the `status` field of the Import Progress response.\n\nAn import that does not have errors will progress through these steps:\n\n* `detecting` - the \"detection\" step of the import is in progress because the request did not include a `vcs` parameter. The import is identifying the type of source control present at the URL.\n* `importing` - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include `commit_count` (the total number of raw commits that will be imported) and `percent` (0 - 100, the current progress through the import).\n* `mapping` - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.\n* `pushing` - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include `push_percent`, which is the percent value reported by `git push` when it is \"Writing objects\".\n* `complete` - the import is complete, and the repository is ready on GitHub.\n\nIf there are problems, you will see one of these in the `status` field:\n\n* `auth_failed` - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `error` - the import encountered an error. The import progress response will include the `failed_step` and an error message. Contact [GitHub Support](https://support.github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com) for more information.\n* `detection_needs_auth` - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `detection_found_nothing` - the importer didn't recognize any source control at the URL. To resolve, [Cancel the import](https://docs.github.com/rest/reference/migrations#cancel-an-import) and [retry](https://docs.github.com/rest/reference/migrations#start-an-import) with the correct URL.\n* `detection_found_multiple` - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a `project_choices` field with the possible project choices as values. To update project choice, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n\n**The project_choices field**\n\nWhen multiple projects are found at the provided URL, the response hash will include a `project_choices` field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.\n\n**Git LFS related fields**\n\nThis section includes details about Git LFS related fields that may be present in the Import Progress response.\n\n* `use_lfs` - describes whether the import has been opted in or out of using Git LFS. The value can be `opt_in`, `opt_out`, or `undecided` if no action has been taken.\n* `has_large_files` - the boolean value describing whether files larger than 100MB were found during the `importing` step.\n* `large_files_size` - the total size in gigabytes of files larger than 100MB found in the originating repository.\n* `large_files_count` - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.", "tags": [ "migrations" ], @@ -54364,7 +54364,7 @@ "subcategoryLabel": "Source imports", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    View the progress of an import.

    \n

    Import status

    \n

    This section includes details about the possible values of the status field of the Import Progress response.

    \n

    An import that does not have errors will progress through these steps:

    \n
      \n
    • detecting - the \"detection\" step of the import is in progress because the request did not include a vcs parameter. The import is identifying the type of source control present at the URL.
    • \n
    • importing - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include commit_count (the total number of raw commits that will be imported) and percent (0 - 100, the current progress through the import).
    • \n
    • mapping - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.
    • \n
    • pushing - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include push_percent, which is the percent value reported by git push when it is \"Writing objects\".
    • \n
    • complete - the import is complete, and the repository is ready on GitHub.
    • \n
    \n

    If there are problems, you will see one of these in the status field:

    \n
      \n
    • auth_failed - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the Update an import section.
    • \n
    • error - the import encountered an error. The import progress response will include the failed_step and an error message. Contact GitHub Support or GitHub Premium Support for more information.
    • \n
    • detection_needs_auth - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the Update an import section.
    • \n
    • detection_found_nothing - the importer didn't recognize any source control at the URL. To resolve, Cancel the import and retry with the correct URL.
    • \n
    • detection_found_multiple - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a project_choices field with the possible project choices as values. To update project choice, please see the Update an import section.
    • \n
    \n

    The project_choices field

    \n

    When multiple projects are found at the provided URL, the response hash will include a project_choices field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.

    \n

    Git LFS related fields

    \n

    This section includes details about Git LFS related fields that may be present in the Import Progress response.

    \n
      \n
    • use_lfs - describes whether the import has been opted in or out of using Git LFS. The value can be opt_in, opt_out, or undecided if no action has been taken.
    • \n
    • has_large_files - the boolean value describing whether files larger than 100MB were found during the importing step.
    • \n
    • large_files_size - the total size in gigabytes of files larger than 100MB found in the originating repository.
    • \n
    • large_files_count - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.
    • \n
    ", + "descriptionHTML": "

    View the progress of an import.

    \n

    Import status

    \n

    This section includes details about the possible values of the status field of the Import Progress response.

    \n

    An import that does not have errors will progress through these steps:

    \n
      \n
    • detecting - the \"detection\" step of the import is in progress because the request did not include a vcs parameter. The import is identifying the type of source control present at the URL.
    • \n
    • importing - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include commit_count (the total number of raw commits that will be imported) and percent (0 - 100, the current progress through the import).
    • \n
    • mapping - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.
    • \n
    • pushing - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include push_percent, which is the percent value reported by git push when it is \"Writing objects\".
    • \n
    • complete - the import is complete, and the repository is ready on GitHub.
    • \n
    \n

    If there are problems, you will see one of these in the status field:

    \n
      \n
    • auth_failed - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the Update an import section.
    • \n
    • error - the import encountered an error. The import progress response will include the failed_step and an error message. Contact GitHub Support or GitHub Premium Support for more information.
    • \n
    • detection_needs_auth - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the Update an import section.
    • \n
    • detection_found_nothing - the importer didn't recognize any source control at the URL. To resolve, Cancel the import and retry with the correct URL.
    • \n
    • detection_found_multiple - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a project_choices field with the possible project choices as values. To update project choice, please see the Update an import section.
    • \n
    \n

    The project_choices field

    \n

    When multiple projects are found at the provided URL, the response hash will include a project_choices field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.

    \n

    Git LFS related fields

    \n

    This section includes details about Git LFS related fields that may be present in the Import Progress response.

    \n
      \n
    • use_lfs - describes whether the import has been opted in or out of using Git LFS. The value can be opt_in, opt_out, or undecided if no action has been taken.
    • \n
    • has_large_files - the boolean value describing whether files larger than 100MB were found during the importing step.
    • \n
    • large_files_size - the total size in gigabytes of files larger than 100MB found in the originating repository.
    • \n
    • large_files_count - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.
    • \n
    ", "responses": [ { "httpStatusCode": "200", @@ -69180,7 +69180,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -69224,7 +69224,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-2.18.json b/lib/rest/static/decorated/ghes-2.18.json index eedf2edd0d..e4ea1ab87d 100644 --- a/lib/rest/static/decorated/ghes-2.18.json +++ b/lib/rest/static/decorated/ghes-2.18.json @@ -33768,7 +33768,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -33810,7 +33810,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -50917,7 +50917,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.18/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.18/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -50961,7 +50961,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-2.19.json b/lib/rest/static/decorated/ghes-2.19.json index b79b9d56fe..d62b99482a 100644 --- a/lib/rest/static/decorated/ghes-2.19.json +++ b/lib/rest/static/decorated/ghes-2.19.json @@ -34331,7 +34331,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -34373,7 +34373,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -51713,7 +51713,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.19/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.19/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -51757,7 +51757,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-2.20.json b/lib/rest/static/decorated/ghes-2.20.json index 22e03dd6ec..d2205c065d 100644 --- a/lib/rest/static/decorated/ghes-2.20.json +++ b/lib/rest/static/decorated/ghes-2.20.json @@ -34802,7 +34802,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -34844,7 +34844,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -52367,7 +52367,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.20/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.20/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -52411,7 +52411,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-2.21.json b/lib/rest/static/decorated/ghes-2.21.json index fe68c3bd22..989484b388 100644 --- a/lib/rest/static/decorated/ghes-2.21.json +++ b/lib/rest/static/decorated/ghes-2.21.json @@ -38451,7 +38451,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -38493,7 +38493,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -56277,7 +56277,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.21/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.21/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -56321,7 +56321,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-2.22.json b/lib/rest/static/decorated/ghes-2.22.json index 0e47905b7a..3dda52d72c 100644 --- a/lib/rest/static/decorated/ghes-2.22.json +++ b/lib/rest/static/decorated/ghes-2.22.json @@ -45916,7 +45916,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -45958,7 +45958,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -63673,7 +63673,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.22/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.22/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -63717,7 +63717,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/ghes-3.0.json b/lib/rest/static/decorated/ghes-3.0.json index 521499e7e5..d88f173d24 100644 --- a/lib/rest/static/decorated/ghes-3.0.json +++ b/lib/rest/static/decorated/ghes-3.0.json @@ -50331,7 +50331,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -50373,7 +50373,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub Enterprise Server Support or GitHub Enterprise Server Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -68346,7 +68346,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@3.0/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@3.0/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -68390,7 +68390,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub Enterprise Server Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/decorated/github.ae.json b/lib/rest/static/decorated/github.ae.json index 068fd90603..ae4350c5bd 100644 --- a/lib/rest/static/decorated/github.ae.json +++ b/lib/rest/static/decorated/github.ae.json @@ -36319,7 +36319,7 @@ } ], "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub AE Support](https://github.com/contact) or [GitHub AE Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub AE Support](https://support.github.com/contact) or [GitHub AE Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -36361,7 +36361,7 @@ "subcategory": "forks", "subcategoryLabel": "Forks", "notes": [], - "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub AE Support or GitHub AE Premium Support.

    ", + "descriptionHTML": "

    Create a fork for the authenticated user.

    \n

    Note: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact GitHub AE Support or GitHub AE Premium Support.

    ", "bodyParameters": [ { "type": "string", @@ -53946,7 +53946,7 @@ } ], "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/github-ae@latest/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/github-ae@latest/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/github-ae@latest/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub AE Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/github-ae@latest/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/github-ae@latest/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/github-ae@latest/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub AE Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], @@ -53990,7 +53990,7 @@ "subcategoryLabel": "Releases", "notes": [], "bodyParameters": [], - "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub AE Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", + "descriptionHTML": "

    This endpoint makes use of a Hypermedia relation to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the upload_url returned in\nthe response of the Create a release endpoint to upload a release asset.

    \n

    You need to use an HTTP client which supports SNI to make calls to this endpoint.

    \n

    Most libraries will set the required Content-Length header automatically. Use the required Content-Type header to provide the media type of the asset. For a list of media types, see Media Types. For example:

    \n

    application/zip

    \n

    GitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.

    \n

    When an upstream failure occurs, you will receive a 502 Bad Gateway status. This may leave an empty asset with a state of starter. It can be safely deleted.

    \n

    Notes:

    \n
      \n
    • GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"List assets for a release\"\nendpoint lists the renamed filenames. For more information and help, contact GitHub AE Support.
    • \n
    • If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.
    • \n
    ", "responses": [ { "httpStatusCode": "201", diff --git a/lib/rest/static/dereferenced/api.github.com.deref.json b/lib/rest/static/dereferenced/api.github.com.deref.json index 65de19fb3d..d02f87eac4 100644 --- a/lib/rest/static/dereferenced/api.github.com.deref.json +++ b/lib/rest/static/dereferenced/api.github.com.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -175345,7 +175345,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Support](https://support.github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -181689,7 +181689,7 @@ "/repos/{owner}/{repo}/import": { "get": { "summary": "Get an import status", - "description": "View the progress of an import.\n\n**Import status**\n\nThis section includes details about the possible values of the `status` field of the Import Progress response.\n\nAn import that does not have errors will progress through these steps:\n\n* `detecting` - the \"detection\" step of the import is in progress because the request did not include a `vcs` parameter. The import is identifying the type of source control present at the URL.\n* `importing` - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include `commit_count` (the total number of raw commits that will be imported) and `percent` (0 - 100, the current progress through the import).\n* `mapping` - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.\n* `pushing` - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include `push_percent`, which is the percent value reported by `git push` when it is \"Writing objects\".\n* `complete` - the import is complete, and the repository is ready on GitHub.\n\nIf there are problems, you will see one of these in the `status` field:\n\n* `auth_failed` - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `error` - the import encountered an error. The import progress response will include the `failed_step` and an error message. Contact [GitHub Support](https://github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com) for more information.\n* `detection_needs_auth` - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `detection_found_nothing` - the importer didn't recognize any source control at the URL. To resolve, [Cancel the import](https://docs.github.com/rest/reference/migrations#cancel-an-import) and [retry](https://docs.github.com/rest/reference/migrations#start-an-import) with the correct URL.\n* `detection_found_multiple` - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a `project_choices` field with the possible project choices as values. To update project choice, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n\n**The project_choices field**\n\nWhen multiple projects are found at the provided URL, the response hash will include a `project_choices` field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.\n\n**Git LFS related fields**\n\nThis section includes details about Git LFS related fields that may be present in the Import Progress response.\n\n* `use_lfs` - describes whether the import has been opted in or out of using Git LFS. The value can be `opt_in`, `opt_out`, or `undecided` if no action has been taken.\n* `has_large_files` - the boolean value describing whether files larger than 100MB were found during the `importing` step.\n* `large_files_size` - the total size in gigabytes of files larger than 100MB found in the originating repository.\n* `large_files_count` - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.", + "description": "View the progress of an import.\n\n**Import status**\n\nThis section includes details about the possible values of the `status` field of the Import Progress response.\n\nAn import that does not have errors will progress through these steps:\n\n* `detecting` - the \"detection\" step of the import is in progress because the request did not include a `vcs` parameter. The import is identifying the type of source control present at the URL.\n* `importing` - the \"raw\" step of the import is in progress. This is where commit data is fetched from the original repository. The import progress response will include `commit_count` (the total number of raw commits that will be imported) and `percent` (0 - 100, the current progress through the import).\n* `mapping` - the \"rewrite\" step of the import is in progress. This is where SVN branches are converted to Git branches, and where author updates are applied. The import progress response does not include progress information.\n* `pushing` - the \"push\" step of the import is in progress. This is where the importer updates the repository on GitHub. The import progress response will include `push_percent`, which is the percent value reported by `git push` when it is \"Writing objects\".\n* `complete` - the import is complete, and the repository is ready on GitHub.\n\nIf there are problems, you will see one of these in the `status` field:\n\n* `auth_failed` - the import requires authentication in order to connect to the original repository. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `error` - the import encountered an error. The import progress response will include the `failed_step` and an error message. Contact [GitHub Support](https://support.github.com/contact) or [GitHub Premium Support](https://premium.githubsupport.com) for more information.\n* `detection_needs_auth` - the importer requires authentication for the originating repository to continue detection. To update authentication for the import, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n* `detection_found_nothing` - the importer didn't recognize any source control at the URL. To resolve, [Cancel the import](https://docs.github.com/rest/reference/migrations#cancel-an-import) and [retry](https://docs.github.com/rest/reference/migrations#start-an-import) with the correct URL.\n* `detection_found_multiple` - the importer found several projects or repositories at the provided URL. When this is the case, the Import Progress response will also include a `project_choices` field with the possible project choices as values. To update project choice, please see the [Update an import](https://docs.github.com/rest/reference/migrations#update-an-import) section.\n\n**The project_choices field**\n\nWhen multiple projects are found at the provided URL, the response hash will include a `project_choices` field, the value of which is an array of hashes each representing a project choice. The exact key/value pairs of the project hashes will differ depending on the version control type.\n\n**Git LFS related fields**\n\nThis section includes details about Git LFS related fields that may be present in the Import Progress response.\n\n* `use_lfs` - describes whether the import has been opted in or out of using Git LFS. The value can be `opt_in`, `opt_out`, or `undecided` if no action has been taken.\n* `has_large_files` - the boolean value describing whether files larger than 100MB were found during the `importing` step.\n* `large_files_size` - the total size in gigabytes of files larger than 100MB found in the originating repository.\n* `large_files_count` - the total number of files larger than 100MB found in the originating repository. To see a list of these files, make a \"Get Large Files\" request.", "tags": [ "migrations" ], @@ -256586,7 +256586,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-2.18.deref.json b/lib/rest/static/dereferenced/ghes-2.18.deref.json index a36ce6710a..df00f4870a 100644 --- a/lib/rest/static/dereferenced/ghes-2.18.deref.json +++ b/lib/rest/static/dereferenced/ghes-2.18.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -118461,7 +118461,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -196443,7 +196443,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.18/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.18/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.18/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-2.19.deref.json b/lib/rest/static/dereferenced/ghes-2.19.deref.json index 5c84c323c1..76b173de06 100644 --- a/lib/rest/static/dereferenced/ghes-2.19.deref.json +++ b/lib/rest/static/dereferenced/ghes-2.19.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -121469,7 +121469,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -199836,7 +199836,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.19/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.19/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.19/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-2.20.deref.json b/lib/rest/static/dereferenced/ghes-2.20.deref.json index 7ab42a5fe4..c5a183abf7 100644 --- a/lib/rest/static/dereferenced/ghes-2.20.deref.json +++ b/lib/rest/static/dereferenced/ghes-2.20.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -123675,7 +123675,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -202807,7 +202807,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.20/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.20/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.20/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-2.21.deref.json b/lib/rest/static/dereferenced/ghes-2.21.deref.json index af1467063f..6e6338401c 100644 --- a/lib/rest/static/dereferenced/ghes-2.21.deref.json +++ b/lib/rest/static/dereferenced/ghes-2.21.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -134793,7 +134793,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -214269,7 +214269,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.21/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.21/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.21/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-2.22.deref.json b/lib/rest/static/dereferenced/ghes-2.22.deref.json index 1d37858101..60a5b5b2af 100644 --- a/lib/rest/static/dereferenced/ghes-2.22.deref.json +++ b/lib/rest/static/dereferenced/ghes-2.22.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -163068,7 +163068,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -242534,7 +242534,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.22/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@2.22/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@2.22/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/ghes-3.0.deref.json b/lib/rest/static/dereferenced/ghes-3.0.deref.json index 7b2843a62b..eabf66bfef 100644 --- a/lib/rest/static/dereferenced/ghes-3.0.deref.json +++ b/lib/rest/static/dereferenced/ghes-3.0.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -168142,7 +168142,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub Enterprise Server Support](https://support.github.com/contact) or [GitHub Enterprise Server Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -247855,7 +247855,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@3.0/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/enterprise-server@3.0/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub Enterprise Server expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub Enterprise Server renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/enterprise-server@3.0/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub Enterprise Server Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], diff --git a/lib/rest/static/dereferenced/github.ae.deref.json b/lib/rest/static/dereferenced/github.ae.deref.json index b0939e309f..331dfd8e68 100644 --- a/lib/rest/static/dereferenced/github.ae.deref.json +++ b/lib/rest/static/dereferenced/github.ae.deref.json @@ -11,7 +11,7 @@ "termsOfService": "https://docs.github.com/articles/github-terms-of-service", "contact": { "name": "Support", - "url": "https://support.github.com" + "url": "https://support.github.com/contact" } }, "tags": [ @@ -127257,7 +127257,7 @@ }, "post": { "summary": "Create a fork", - "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub AE Support](https://github.com/contact) or [GitHub AE Premium Support](https://premium.githubsupport.com).", + "description": "Create a fork for the authenticated user.\n\n**Note**: Forking a Repository happens asynchronously. You may have to wait a short period of time before you can access the git objects. If this takes longer than 5 minutes, be sure to contact [GitHub AE Support](https://support.github.com/contact) or [GitHub AE Premium Support](https://premium.githubsupport.com).", "tags": [ "repos" ], @@ -206585,7 +206585,7 @@ }, "post": { "summary": "Upload a release asset", - "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/github-ae@latest/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/github-ae@latest/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/github-ae@latest/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub AE Support](https://github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", + "description": "This endpoint makes use of [a Hypermedia relation](https://docs.github.com/github-ae@latest/rest/overview/resources-in-the-rest-api#hypermedia) to determine which URL to access. The endpoint you call to upload release assets is specific to your release. Use the `upload_url` returned in\nthe response of the [Create a release endpoint](https://docs.github.com/github-ae@latest/rest/reference/repos#create-a-release) to upload a release asset.\n\nYou need to use an HTTP client which supports [SNI](http://en.wikipedia.org/wiki/Server_Name_Indication) to make calls to this endpoint.\n\nMost libraries will set the required `Content-Length` header automatically. Use the required `Content-Type` header to provide the media type of the asset. For a list of media types, see [Media Types](https://www.iana.org/assignments/media-types/media-types.xhtml). For example: \n\n`application/zip`\n\nGitHub AE expects the asset data in its raw binary form, rather than JSON. You will send the raw binary content of the asset as the request body. Everything else about the endpoint is the same as the rest of the API. For example,\nyou'll still need to pass your authentication to be able to upload an asset.\n\nWhen an upstream failure occurs, you will receive a `502 Bad Gateway` status. This may leave an empty asset with a state of `starter`. It can be safely deleted.\n\n**Notes:**\n* GitHub AE renames asset filenames that have special characters, non-alphanumeric characters, and leading or trailing periods. The \"[List assets for a release](https://docs.github.com/github-ae@latest/rest/reference/repos#list-assets-for-a-release)\"\nendpoint lists the renamed filenames. For more information and help, contact [GitHub AE Support](https://support.github.com/contact).\n* If you upload an asset with the same filename as another uploaded asset, you'll receive an error and must delete the old file before you can re-upload the new asset.", "tags": [ "repos" ], From 62059e4a7110a200b9f06bdb081c33e30b959108 Mon Sep 17 00:00:00 2001 From: mc <42146119+mchammer01@users.noreply.github.com> Date: Mon, 18 Jan 2021 10:45:31 +0000 Subject: [PATCH 59/65] Apply suggestions from code review Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com> --- content/developers/overview/secret-scanning.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/content/developers/overview/secret-scanning.md b/content/developers/overview/secret-scanning.md index 44a6a8a924..d8b576f449 100644 --- a/content/developers/overview/secret-scanning.md +++ b/content/developers/overview/secret-scanning.md @@ -13,7 +13,7 @@ versions: When a match of your secret format is found in a public repository, a payload is sent to an HTTP endpoint of your choice. -When a match of your secret format is found in a private repository configured for {% data variables.product.prodname_secret_scanning %}, then repository admins are alerted and can view and manage the {% data variables.product.prodname_secret_scanning %} results on {% data variables.product.prodname_dotcom %}. For more information, see "[Managing alerts from {% data variables.product.prodname_secret_scanning %}](/github/administering-a-repository/managing-alerts-from-secret-scanning)". +When a match of your secret format is found in a private repository configured for {% data variables.product.prodname_secret_scanning %}, then repository admins are alerted and can view and manage the {% data variables.product.prodname_secret_scanning %} results on {% data variables.product.prodname_dotcom %}. For more information, see "[Managing alerts from {% data variables.product.prodname_secret_scanning %}](/github/administering-a-repository/managing-alerts-from-secret-scanning)." {% note %} @@ -42,7 +42,7 @@ The following diagram summarizes the {% data variables.product.prodname_secret_s #### Contact {% data variables.product.prodname_dotcom %} to get the process started -To get the enrollment process started, email secret-scanning@github.com. +To get the enrollment process started, email secret-scanning@github.com. You will receive details on the {% data variables.product.prodname_secret_scanning %} program, and you will need to agree to {% data variables.product.prodname_dotcom %}'s terms of participation before proceeding. @@ -284,11 +284,11 @@ For {% data variables.product.prodname_secret_scanning %} in public repositories #### Provide feedback for false positives -We collect feedback on the validity of the detected individual secrets in partner responses. Email us at secret-scanning@github.com if you wish to to take part, and get feedback collection enabled. +We collect feedback on the validity of the detected individual secrets in partner responses. If you wish to take part, email us at secret-scanning@github.com. -When we report secrets to you, we send a JSON array with each element containing the token, type identifier, and commit URL. When you send us feedback, you send us information about whether the detected token was a real or false credential. +When we report secrets to you, we send a JSON array with each element containing the token, type identifier, and commit URL. When you send us feedback, you send us information about whether the detected token was a real or false credential. We accept feedback in the following formats. -You can find below the two response formats that we support in terms of feedback: +You can send us the raw token: ``` [ @@ -304,7 +304,7 @@ You may also provide the token in hashed form after performing a one way cryptog ``` [ { - "token_hash": "The SHA 256 hashed form of the raw token", + "token_hash": "The SHA-256 hashed form of the raw token", "token_type": "ACompany_API_token", "label": "false_positive" } @@ -317,8 +317,7 @@ A few important points: {% note %} -**Note:** Our request timeout is set to be higher (that is, 30 seconds) for responding partners with false positives data. If you require a timeout larger than 30 seconds, email us at secret-scanning@github.com. +**Note:** Our request timeout is set to be higher (that is, 30 seconds) for partners who provide data about false positives. If you require a timeout higher than 30 seconds, email us at secret-scanning@github.com. {% endnote %} - From 6a0d679ef445df798437d976a34f110dafbd25e2 Mon Sep 17 00:00:00 2001 From: mchammer01 <42146119+mchammer01@users.noreply.github.com> Date: Mon, 18 Jan 2021 10:53:41 +0000 Subject: [PATCH 60/65] add mailto to missed occurrence of secret scanning email address --- content/developers/overview/secret-scanning.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/developers/overview/secret-scanning.md b/content/developers/overview/secret-scanning.md index d8b576f449..9f7f0cb018 100644 --- a/content/developers/overview/secret-scanning.md +++ b/content/developers/overview/secret-scanning.md @@ -54,7 +54,7 @@ To scan for your secrets, {% data variables.product.prodname_dotcom %} needs the * A regular expression which finds the secret type. Be as precise as possible, because this will reduce the number of false positives. * The URL of the endpoint that receives messages from {% data variables.product.prodname_dotcom %}. This does not have to be unique for each secret type. -Send this information to secret-scanning@github.com. +Send this information to secret-scanning@github.com. #### Create a secret alert service From c9ab1b1ad132d44b6e3537dd340e5c9cde2c2ba8 Mon Sep 17 00:00:00 2001 From: mc <42146119+mchammer01@users.noreply.github.com> Date: Mon, 18 Jan 2021 12:02:55 +0000 Subject: [PATCH 61/65] Apply suggestions from code review Co-authored-by: Felicity Chapman --- .../repository-permission-levels-for-an-organization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md index 13b6f66adf..cb8e0667dd 100644 --- a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md +++ b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md @@ -46,7 +46,7 @@ In addition to managing organization-level settings, organization owners have ad {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} {% note %} -**Note:** Repository permissions required for actions related to security features are listed in "[Permission requirements for security features](#permission-requirements-for-security-features)" below. +**Note:** Repository permissions required to use security features are listed in "[Permission requirements for security features](#permission-requirements-for-security-features)" below. {% endnote %} {% endif %} From d9167f1449e44885307877307ff7e49db23b14cd Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Mon, 18 Jan 2021 07:04:46 -0500 Subject: [PATCH 62/65] chore: Add missing code fence languages (#772) * chore: Add missing code fence languages * Update content/actions/creating-actions/dockerfile-support-for-github-actions.md * Add raw & endraw markers around shell content See review comment by @rachmari * Add raw & endraw markers around shell content See review comment by @rachmari * Remove language from code fences to avoid the problem of replaceable text indicates like not showing up in the output page. Co-authored-by: hubwriter --- content/README.md | 2 +- .../dockerfile-support-for-github-actions.md | 9 ++-- .../setting-exit-codes-for-actions.md | 2 + .../guides/building-and-testing-nodejs.md | 2 +- ...hing-dependencies-to-speed-up-workflows.md | 8 ++-- .../guides/publishing-nodejs-packages.md | 4 +- .../storing-workflow-data-as-artifacts.md | 2 +- ...a-proxy-server-with-self-hosted-runners.md | 2 +- .../adding-a-workflow-status-badge.md | 8 ++-- .../workflow-commands-for-github-actions.md | 4 +- .../evacuating-a-cluster-node.md | 14 ++++++- .../initializing-the-cluster.md | 2 +- ...manually-syncing-actions-from-githubcom.md | 2 +- .../creating-a-pre-receive-hook-script.md | 42 +++++++++---------- .../migrating-to-internal-repositories.md | 4 +- .../creating-a-github-app-from-a-manifest.md | 4 +- .../creating-ci-tests-with-the-checks-api.md | 2 +- ...g-and-authorizing-users-for-github-apps.md | 2 +- .../developers/overview/secret-scanning.md | 4 +- ...ngle-issue-template-for-your-repository.md | 2 +- ...a-merge-conflict-using-the-command-line.md | 16 +++---- .../working-with-pre-receive-hooks.md | 2 +- ...-codeql-code-scanning-in-your-ci-system.md | 10 ++--- .../about-github-pages-and-jekyll.md | 4 +- ...yll-build-errors-for-github-pages-sites.md | 4 +- ...-to-your-github-pages-site-using-jekyll.md | 2 +- ...tom-404-page-for-your-github-pages-site.md | 2 +- ...yll-build-errors-for-github-pages-sites.md | 2 +- .../basic-writing-and-formatting-syntax.md | 16 +++---- .../organizing-information-with-tables.md | 10 ++--- .../graphql/guides/introduction-to-graphql.md | 38 ++++++++--------- ...n-github-insights-and-github-enterprise.md | 2 +- ...ache-maven-for-use-with-github-packages.md | 10 ++--- ...guring-npm-for-use-with-github-packages.md | 2 +- ...g-rubygems-for-use-with-github-packages.md | 6 +-- .../manage-packages/deleting-a-package.md | 4 +- 36 files changed, 132 insertions(+), 119 deletions(-) diff --git a/content/README.md b/content/README.md index 35703a215a..69da2ee8a7 100644 --- a/content/README.md +++ b/content/README.md @@ -269,7 +269,7 @@ https://github-images.s3.amazonaws.com/enterprise/2.20/assets/images/help/profil Sometimes you want to link to a Dotcom-only article in Enterprise content and you don't want the link to be Enterprise-ified. To prevent the transformation, write the link using HTML and add a class of `dotcom-only`. For example: -``` +```html GitHub's Terms of Service ``` diff --git a/content/actions/creating-actions/dockerfile-support-for-github-actions.md b/content/actions/creating-actions/dockerfile-support-for-github-actions.md index 68f93976d7..dba9c8dd1e 100644 --- a/content/actions/creating-actions/dockerfile-support-for-github-actions.md +++ b/content/actions/creating-actions/dockerfile-support-for-github-actions.md @@ -48,20 +48,21 @@ The Docker `ENTRYPOINT` instruction has a _shell_ form and _exec_ form. The Dock If you configure your container to use the _exec_ form of the `ENTRYPOINT` instruction, the `args` configured in the action's metadata file won't run in a command shell. If the action's `args` contain an environment variable, the variable will not be substituted. For example, using the following _exec_ format will not print the value stored in `$GITHUB_SHA`, but will instead print `"$GITHUB_SHA"`. -``` +```dockerfile ENTRYPOINT ["echo $GITHUB_SHA"] ``` If you want variable substitution, then either use the _shell_ form or execute a shell directly. For example, using the following _exec_ format, you can execute a shell to print the value stored in the `GITHUB_SHA` environment variable. -``` +```dockerfile ENTRYPOINT ["sh", "-c", "echo $GITHUB_SHA"] -```` +``` To supply `args` defined in the action's metadata file to a Docker container that uses the _exec_ form in the `ENTRYPOINT`, we recommend creating a shell script called `entrypoint.sh` that you call from the `ENTRYPOINT` instruction: ##### Example *Dockerfile* -``` + +```dockerfile # Container image that runs your code FROM debian:9.5-slim diff --git a/content/actions/creating-actions/setting-exit-codes-for-actions.md b/content/actions/creating-actions/setting-exit-codes-for-actions.md index 1e550d3bbc..2a733849d5 100644 --- a/content/actions/creating-actions/setting-exit-codes-for-actions.md +++ b/content/actions/creating-actions/setting-exit-codes-for-actions.md @@ -41,11 +41,13 @@ For more information, see "[Creating a JavaScript action](/articles/creating-a-j If you are creating a Docker container action, you can set a failure exit code in your `entrypoint.sh` script. For example: +{% raw %} ``` if ; then echo "Game over!" exit 1 fi ``` +{% endraw %} For more information, see "[Creating a Docker container action](/articles/creating-a-docker-container-action)." diff --git a/content/actions/guides/building-and-testing-nodejs.md b/content/actions/guides/building-and-testing-nodejs.md index 6fa457742b..480d359be1 100644 --- a/content/actions/guides/building-and-testing-nodejs.md +++ b/content/actions/guides/building-and-testing-nodejs.md @@ -220,7 +220,7 @@ steps: The example above creates an *.npmrc* file with the following contents: -``` +```ini //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} @octocat:registry=https://registry.npmjs.org/ always-auth=true diff --git a/content/actions/guides/caching-dependencies-to-speed-up-workflows.md b/content/actions/guides/caching-dependencies-to-speed-up-workflows.md index d450d7ae52..1e43aea478 100644 --- a/content/actions/guides/caching-dependencies-to-speed-up-workflows.md +++ b/content/actions/guides/caching-dependencies-to-speed-up-workflows.md @@ -124,14 +124,14 @@ A cache key can include any of the contexts, functions, literals, and operators Using expressions to create a `key` allows you to automatically create a new cache when dependencies have changed. For example, you can create a `key` using an expression that calculates the hash of an npm `package-lock.json` file. {% raw %} -``` +```yaml npm-${{ hashFiles('package-lock.json') }} ``` {% endraw %} {% data variables.product.prodname_dotcom %} evaluates the expression `hash "package-lock.json"` to derive the final `key`. -``` +```yaml npm-d5ea0750 ``` @@ -144,7 +144,7 @@ You can provide a list of restore keys to use when there is a cache miss on `key #### Example using multiple restore keys {% raw %} -``` +```yaml restore-keys: | npm-foobar-${{ hashFiles('package-lock.json') }} npm-foobar- @@ -155,7 +155,7 @@ restore-keys: | The runner evaluates the expressions, which resolve to these `restore-keys`: {% raw %} -``` +```yaml restore-keys: | npm-foobar-d5ea0750 npm-foobar- diff --git a/content/actions/guides/publishing-nodejs-packages.md b/content/actions/guides/publishing-nodejs-packages.md index ce467dd525..8b79ba457c 100644 --- a/content/actions/guides/publishing-nodejs-packages.md +++ b/content/actions/guides/publishing-nodejs-packages.md @@ -78,7 +78,7 @@ jobs: In the example above, the `setup-node` action creates an *.npmrc* file on the runner with the following contents: -``` +```ini //registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN} registry=https://registry.npmjs.org/ always-auth=true @@ -140,7 +140,7 @@ jobs: The `setup-node` action creates an *.npmrc* file on the runner. When you use the `scope` input to the `setup-node` action, the *.npmrc* file includes the scope prefix. By default, the `setup-node` action sets the scope in the *.npmrc* file to the account that contains that workflow file. -``` +```ini //npm.pkg.github.com/:_authToken=${NODE_AUTH_TOKEN} @octocat:registry=https://npm.pkg.github.com always-auth=true diff --git a/content/actions/guides/storing-workflow-data-as-artifacts.md b/content/actions/guides/storing-workflow-data-as-artifacts.md index fe6aac29ed..763158ff58 100644 --- a/content/actions/guides/storing-workflow-data-as-artifacts.md +++ b/content/actions/guides/storing-workflow-data-as-artifacts.md @@ -114,7 +114,7 @@ jobs: You can define a custom retention period for individual artifacts created by a workflow. When using a workflow to create a new artifact, you can use `retention-days` with the `upload-artifact` action. This example demonstrates how to set a custom retention period of 5 days for the artifact named `my-artifact`: -``` +```yaml - name: 'Upload Artifact' uses: actions/upload-artifact@v2 with: diff --git a/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md b/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md index 2dc3f1fc96..c3b60531c3 100644 --- a/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md +++ b/content/actions/hosting-your-own-runners/using-a-proxy-server-with-self-hosted-runners.md @@ -38,7 +38,7 @@ If setting environment variables is not practical, you can set the proxy configu An example _.env_ proxy configuration is shown below: -``` +```ini https_proxy=http://proxy.local:8080 no_proxy=example.com,myserver.local:443 ``` diff --git a/content/actions/managing-workflow-runs/adding-a-workflow-status-badge.md b/content/actions/managing-workflow-runs/adding-a-workflow-status-badge.md index 162499b98a..523e8d551c 100644 --- a/content/actions/managing-workflow-runs/adding-a-workflow-status-badge.md +++ b/content/actions/managing-workflow-runs/adding-a-workflow-status-badge.md @@ -34,7 +34,7 @@ https://github.com///workflows//badge.svg This Markdown example adds a status badge for a workflow with the name "Greet Everyone." The `OWNER` of the repository is the `actions` organization and the `REPOSITORY` name is `hello-world`. -``` +```markdown ![example workflow name](https://github.com/actions/hello-world/workflows/Greet%20Everyone/badge.svg) ``` @@ -42,7 +42,7 @@ This Markdown example adds a status badge for a workflow with the name "Greet Ev This Markdown example adds a status badge for a workflow with the file path `.github/workflows/main.yml`. The `OWNER` of the repository is the `actions` organization and the `REPOSITORY` name is `hello-world`. -``` +```markdown ![example workflow file path](https://github.com/actions/hello-world/workflows/.github/workflows/main.yml/badge.svg) ``` @@ -50,7 +50,7 @@ This Markdown example adds a status badge for a workflow with the file path `.gi This Markdown example adds a status badge for a branch with the name `feature-1`. -``` +```markdown ![example branch parameter](https://github.com/actions/hello-world/workflows/Greet%20Everyone/badge.svg?branch=feature-1) ``` @@ -58,6 +58,6 @@ This Markdown example adds a status badge for a branch with the name `feature-1` This Markdown example adds a badge that displays the status of workflow runs triggered by the `pull_request` event. -``` +```markdown ![example event parameter](https://github.com/actions/hello-world/workflows/Greet%20Everyone/badge.svg?event=pull_request) ``` diff --git a/content/actions/reference/workflow-commands-for-github-actions.md b/content/actions/reference/workflow-commands-for-github-actions.md index a66233c2af..75aab6a867 100644 --- a/content/actions/reference/workflow-commands-for-github-actions.md +++ b/content/actions/reference/workflow-commands-for-github-actions.md @@ -253,7 +253,7 @@ During the execution of a workflow, the runner generates temporary files that ca **Warning:** Powershell does not use UTF-8 by default. Make sure you write files using the correct encoding. For example, you need to set UTF-8 encoding when you set the path: -``` +```yaml steps: - run: echo "mypath" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append ``` @@ -287,7 +287,7 @@ For multiline strings, you may use a delimiter with the following syntax. ##### Example In this example, we use `EOF` as a delimiter and set the `JSON_RESPONSE` environment variable to the value of the curl response. -``` +```yaml steps: - name: Set the value id: step_one diff --git a/content/admin/enterprise-management/evacuating-a-cluster-node.md b/content/admin/enterprise-management/evacuating-a-cluster-node.md index ce81346f75..c429e92707 100644 --- a/content/admin/enterprise-management/evacuating-a-cluster-node.md +++ b/content/admin/enterprise-management/evacuating-a-cluster-node.md @@ -18,36 +18,46 @@ If you're taking a node offline that has any data services (like git, pages, or $ ghe-config cluster._hostname_.uuid ``` -2. You'll need to monitor the status of your node while the data is being copied. Ideally, the node shouldn't be taken offline until the copying is complete. To monitor the status of your node, run any of the following commands: +2. You'll need to monitor the status of your node while the data is being copied. Ideally, the node shouldn't be taken offline until the copying is complete. To monitor the status of your node, run any of the following commands: For Git ``` ghe-spokes evac-status ``` For {% data variables.product.prodname_pages %} + {% raw %} ``` echo "select count(*) from pages_replicas where host = 'pages-server-'" | ghe-dbconsole -y ``` + {% endraw %} For storage ``` ghe-storage evacuation-status ``` -3. After the copying is complete, you can evacuate the storage service. Run any of the following commands: +3. After the copying is complete, you can evacuate the storage service. Run any of the following commands: For Git + {% raw %} ``` ghe-spokes server evacuate git-server- ``` + {% endraw %} For {% data variables.product.prodname_pages %} + {% raw %} ``` ghe-dpages evacuate pages-server- ``` + {% endraw %} For storage, take the node offline + {% raw %} ``` ghe-storage offline storage-server- ``` + {% endraw %} then evacuate + {% raw %} ``` ghe-storage evacuate storage-server- ``` + {% endraw %} diff --git a/content/admin/enterprise-management/initializing-the-cluster.md b/content/admin/enterprise-management/initializing-the-cluster.md index b6ff1105a8..1fc88c484a 100644 --- a/content/admin/enterprise-management/initializing-the-cluster.md +++ b/content/admin/enterprise-management/initializing-the-cluster.md @@ -46,7 +46,7 @@ The names of the nodes can be any valid hostname you choose. The names are set a Specify the first cluster node you configured as the MySQL primary via `mysql-server` and `mysql-master`. -``` +```ini [cluster] mysql-master = ghe-data-node-1 redis-master = ghe-data-node-1 diff --git a/content/admin/github-actions/manually-syncing-actions-from-githubcom.md b/content/admin/github-actions/manually-syncing-actions-from-githubcom.md index 63aa2f5b9c..f36947c4bc 100644 --- a/content/admin/github-actions/manually-syncing-actions-from-githubcom.md +++ b/content/admin/github-actions/manually-syncing-actions-from-githubcom.md @@ -63,7 +63,7 @@ This example demonstrates using the `actions-sync` tool to sync an individual ac * You can sync multiple actions by replacing the `--repo-name` parameter with `--repo-name-list` or `--repo-name-list-file`. For more information, see the [`actions-sync` README](https://github.com/actions/actions-sync#actions-sync). 1. After the action repository is created on your enterprise instance, people in your enterprise can use the destination repository to reference the action in their workflows. For the example action shown above: - ``` + ```yaml uses: synced-actions/docker-build-push-action@v1 ``` diff --git a/content/admin/policies/creating-a-pre-receive-hook-script.md b/content/admin/policies/creating-a-pre-receive-hook-script.md index f425ea8e24..2022ef49c5 100644 --- a/content/admin/policies/creating-a-pre-receive-hook-script.md +++ b/content/admin/policies/creating-a-pre-receive-hook-script.md @@ -11,7 +11,7 @@ versions: You can see examples of pre-receive hooks for {% data variables.product.prodname_ghe_server %} in the [`github/platform-samples` repository](https://github.com/github/platform-samples/tree/master/pre-receive-hooks). ### Writing a pre-receive hook script -A pre-receive hook script executes in a pre-receive hook environment on the {% data variables.product.prodname_ghe_server %} appliance. When you create a pre-receive hook script, consider the available input, output, exit-status and environment variables. +A pre-receive hook script executes in a pre-receive hook environment on the {% data variables.product.prodname_ghe_server %} appliance. When you create a pre-receive hook script, consider the available input, output, exit-status and environment variables. #### Input (stdin) After a push occurs and before any refs are updated on the remote repository, the `git-receive-pack` process invokes the pre-receive hook script with the standard input of one line per ref to be updated: @@ -94,30 +94,30 @@ You can test a pre-receive hook script locally before you create or update it on 2. Create a file called `Dockerfile.dev` containing: - ``` - FROM gliderlabs/alpine:3.3 - RUN \ - apk add --no-cache git openssh bash && \ - ssh-keygen -A && \ - sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \ - adduser git -D -G root -h /home/git -s /bin/bash && \ - passwd -d git && \ - su git -c "mkdir /home/git/.ssh && \ - ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P '' && \ - mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && \ - mkdir /home/git/test.git && \ - git --bare init /home/git/test.git" + ```dockerfile + FROM gliderlabs/alpine:3.3 + RUN \ + apk add --no-cache git openssh bash && \ + ssh-keygen -A && \ + sed -i "s/#AuthorizedKeysFile/AuthorizedKeysFile/g" /etc/ssh/sshd_config && \ + adduser git -D -G root -h /home/git -s /bin/bash && \ + passwd -d git && \ + su git -c "mkdir /home/git/.ssh && \ + ssh-keygen -t ed25519 -f /home/git/.ssh/id_ed25519 -P '' && \ + mv /home/git/.ssh/id_ed25519.pub /home/git/.ssh/authorized_keys && \ + mkdir /home/git/test.git && \ + git --bare init /home/git/test.git" - VOLUME ["/home/git/.ssh", "/home/git/test.git/hooks"] - WORKDIR /home/git + VOLUME ["/home/git/.ssh", "/home/git/test.git/hooks"] + WORKDIR /home/git - CMD ["/usr/sbin/sshd", "-D"] - ``` + CMD ["/usr/sbin/sshd", "-D"] + ``` -3. Create a test pre-receive script called `always_reject.sh`. This example script will reject all pushes, which is useful for locking a repository: + 3. Create a test pre-receive script called `always_reject.sh`. This example script will reject all pushes, which is useful for locking a repository: - ``` - #!/usr/bin/env bash + ```shell + #!/usr/bin/env bash echo "error: rejecting all pushes" exit 1 diff --git a/content/admin/user-management/migrating-to-internal-repositories.md b/content/admin/user-management/migrating-to-internal-repositories.md index fbd80a13f9..509a9e1a11 100644 --- a/content/admin/user-management/migrating-to-internal-repositories.md +++ b/content/admin/user-management/migrating-to-internal-repositories.md @@ -33,11 +33,11 @@ If you don't have private mode enabled, the migration script will have no effect 1. Connect to the administrative shell. For more information, see "[Accessing the administrative shell (SSH)](/enterprise/admin/installation/accessing-the-administrative-shell-ssh)." 2. Navigate to the `/data/github/current` directory. - ``` + ```shell cd /data/github/current ``` 3. Run the migration command. - ``` + ```shell sudo bin/safe-ruby lib/github/transitions/20191210220630_convert_public_ghes_repos_to_internal.rb --verbose -w | tee -a /tmp/convert_public_ghes_repos_to_internal.log ``` diff --git a/content/developers/apps/creating-a-github-app-from-a-manifest.md b/content/developers/apps/creating-a-github-app-from-a-manifest.md index 83cd4644dd..7c18a8b460 100644 --- a/content/developers/apps/creating-a-github-app-from-a-manifest.md +++ b/content/developers/apps/creating-a-github-app-from-a-manifest.md @@ -80,7 +80,7 @@ Name | Type | Description This example uses a form on a web page with a button that triggers the `POST` request for a user account: -``` +```html
    Create a GitHub App Manifest:
    @@ -111,7 +111,7 @@ This example uses a form on a web page with a button that triggers the `POST` re ``` This example uses a form on a web page with a button that triggers the `POST` request for an organization account. Replace `ORGANIZATION` with the name of the organization account where you want to create the app. -``` +```html Create a GitHub App Manifest:
    diff --git a/content/developers/apps/creating-ci-tests-with-the-checks-api.md b/content/developers/apps/creating-ci-tests-with-the-checks-api.md index be09ec94e0..3c498bff5c 100644 --- a/content/developers/apps/creating-ci-tests-with-the-checks-api.md +++ b/content/developers/apps/creating-ci-tests-with-the-checks-api.md @@ -724,7 +724,7 @@ To push to a repository, your app must have write permissions for "Repository co In order to commit files, Git must know which [username](/articles/setting-your-username-in-git/) and [email](/articles/setting-your-commit-email-address-in-git/) to associate with the commit. Add two more environment variables in your `.env` file to store the name (`GITHUB_APP_USER_NAME`) and email (`GITHUB_APP_USER_EMAIL`) settings. Your name can be the name of your app and the email can be any email you'd like for this example. For example: -``` +```ini GITHUB_APP_USER_NAME=Octoapp GITHUB_APP_USER_EMAIL=octoapp@octo-org.com ``` diff --git a/content/developers/apps/identifying-and-authorizing-users-for-github-apps.md b/content/developers/apps/identifying-and-authorizing-users-for-github-apps.md index ae02a509fc..fc0202be05 100644 --- a/content/developers/apps/identifying-and-authorizing-users-for-github-apps.md +++ b/content/developers/apps/identifying-and-authorizing-users-for-github-apps.md @@ -89,7 +89,7 @@ Name | Type | Description By default, the response takes the following form. The response parameters `expires_in`, `refresh_token`, and `refresh_token_expires_in` are only returned when you enable the beta for expiring user-to-server access tokens. -``` +```json { "access_token": "e72e16c7e42f292c6912e7710c838347ae178b4a", "expires_in": "28800", diff --git a/content/developers/overview/secret-scanning.md b/content/developers/overview/secret-scanning.md index 054637e2a5..232bfa2707 100644 --- a/content/developers/overview/secret-scanning.md +++ b/content/developers/overview/secret-scanning.md @@ -61,7 +61,7 @@ Create a public, internet accessible HTTP endpoint at the URL you provided to us ##### Example POST sent to your endpoint -``` +```http POST / HTTP/1.1 Host: HOST Accept: */* @@ -95,7 +95,7 @@ Assuming you receive the following message, the code snippets below demonstrate The code also assumes you've set an environment variable called `GITHUB_PRODUCTION_TOKEN` with a generated PAT (https://github.com/settings/tokens). The token does not need any permissions set. **Sample message sent to verify endpoint** -``` +```http POST / HTTP/1.1 Host: HOST Accept: */* diff --git a/content/github/building-a-strong-community/manually-creating-a-single-issue-template-for-your-repository.md b/content/github/building-a-strong-community/manually-creating-a-single-issue-template-for-your-repository.md index 35a090bdab..8cb5adf5ce 100644 --- a/content/github/building-a-strong-community/manually-creating-a-single-issue-template-for-your-repository.md +++ b/content/github/building-a-strong-community/manually-creating-a-single-issue-template-for-your-repository.md @@ -18,7 +18,7 @@ You can add YAML frontmatter to each issue template to pre-fill the issue title, Here is example YAML front matter. -``` +```yaml --- name: Tracking issue about: Use this template for tracking new features. diff --git a/content/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line.md b/content/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line.md index c6ce427518..5dae3a1540 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line.md +++ b/content/github/collaborating-with-issues-and-pull-requests/resolving-a-merge-conflict-using-the-command-line.md @@ -46,14 +46,14 @@ For example, if you and another person both edited the file _styleguide.md_ on t 4. Open your favorite text editor, such as [Atom](https://atom.io/), and navigate to the file that has merge conflicts. 5. To see the beginning of the merge conflict in your file, search the file for the conflict marker `<<<<<<<`. When you open the file in your text editor, you'll see the changes from the HEAD or base branch after the line `<<<<<<< HEAD`. Next, you'll see `=======`, which divides your changes from the changes in the other branch, followed by `>>>>>>> BRANCH-NAME`. In this example, one person wrote "open an issue" in the base or HEAD branch and another person wrote "ask your question in IRC" in the compare branch or `branch-a`. - ``` -If you have questions, please -<<<<<<< HEAD -open an issue -======= -ask your question in IRC. ->>>>>>> branch-a - ```` + ``` + If you have questions, please + <<<<<<< HEAD + open an issue + ======= + ask your question in IRC. + >>>>>>> branch-a + ``` {% data reusables.pull_requests.decide-how-to-resolve-competing-line-change-merge-conflict %} In this example, both changes are incorporated into the final merge: ```shell diff --git a/content/github/collaborating-with-issues-and-pull-requests/working-with-pre-receive-hooks.md b/content/github/collaborating-with-issues-and-pull-requests/working-with-pre-receive-hooks.md index 85001ffa31..5b78492e23 100644 --- a/content/github/collaborating-with-issues-and-pull-requests/working-with-pre-receive-hooks.md +++ b/content/github/collaborating-with-issues-and-pull-requests/working-with-pre-receive-hooks.md @@ -11,7 +11,7 @@ Pre-receive hooks run tests on code pushed to a repository to ensure contributio If your push isn't accepted, you'll see an error message corresponding to the failed pre-receive hook. -``` +```shell $ git push Counting objects: 3, done. Delta compression using up to 4 threads. diff --git a/content/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-codeql-code-scanning-in-your-ci-system.md b/content/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-codeql-code-scanning-in-your-ci-system.md index 2e9b9ce638..944f9c4a30 100644 --- a/content/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-codeql-code-scanning-in-your-ci-system.md +++ b/content/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-codeql-code-scanning-in-your-ci-system.md @@ -21,7 +21,7 @@ To integrate {% data variables.product.prodname_code_scanning %} into your CI sy In general, you invoke the {% data variables.product.prodname_codeql_runner %} as follows. -``` +```shell $ /path/to-runner/codeql-runner-OS ``` @@ -40,7 +40,7 @@ The {% data variables.product.prodname_codeql_runner %} automatically detects an To override automatic language detection, run the `init` command with the `--languages` flag, followed by a comma-separated list of language keywords. The keywords for the supported languages are `cpp`, `csharp`, `go`, `java`, `javascript`, and `python`. -``` +```shell $ /path/to-runner/codeql-runner-linux init --languages cpp,java ``` @@ -58,7 +58,7 @@ For more information, see "[Using a custom configuration file](#using-a-custom-c In the following example, the `+` symbol ensures that the {% data variables.product.prodname_codeql_runner %} uses the additional queries together with any queries specified in the referenced configuration file. -``` +```shell $ /path/to-runner/codeql-runner-linux init --config-file .github/codeql/codeql-config.yml --queries +security-and-quality,octo-org/python-qlpack/show_ifs.ql@main ``` @@ -71,7 +71,7 @@ The configuration file is a YAML file. It uses syntax similar to the workflow sy Use the `--config-file` flag of the `init` command to specify the configuration file. The value of `--config-file` is the path to the configuration file that you want to use. This example loads the configuration file _.github/codeql/codeql-config.yml_. -``` +```shell $ /path/to-runner/codeql-runner-linux init --config-file .github/codeql/codeql-config.yml ``` @@ -87,7 +87,7 @@ For many common build systems, the {% data variables.product.prodname_codeql_run The `autobuild` process only ever attempts to build _one_ compiled language for a repository. The language automatically selected for analysis is the language with the most files. If you want to choose a language explicitly, use the `--language` flag of the `autobuild` command. -``` +```shell $ /path/to-runner/codeql-runner-linux autobuild --language csharp ``` diff --git a/content/github/working-with-github-pages/about-github-pages-and-jekyll.md b/content/github/working-with-github-pages/about-github-pages-and-jekyll.md index 07804937c6..f15e93e71a 100644 --- a/content/github/working-with-github-pages/about-github-pages-and-jekyll.md +++ b/content/github/working-with-github-pages/about-github-pages-and-jekyll.md @@ -38,7 +38,7 @@ You can configure most Jekyll settings, such as your site's theme and plugins, b Some configuration settings cannot be changed for {% data variables.product.prodname_pages %} sites. -``` +```yaml lsi: false safe: true source: [your repo's top level directory] @@ -111,7 +111,7 @@ By default, code blocks on your site will be highlighted by Jekyll. Jekyll uses If you want to use another highlighter, such as `highlight.js`, you must disable Jekyll's syntax highlighting by updating your project's *_config.yml* file. -``` +```yaml kramdown: syntax_highlighter_opts: disable : true diff --git a/content/github/working-with-github-pages/about-jekyll-build-errors-for-github-pages-sites.md b/content/github/working-with-github-pages/about-jekyll-build-errors-for-github-pages-sites.md index dc00414587..d1d49acece 100644 --- a/content/github/working-with-github-pages/about-jekyll-build-errors-for-github-pages-sites.md +++ b/content/github/working-with-github-pages/about-jekyll-build-errors-for-github-pages-sites.md @@ -44,13 +44,13 @@ You can see build failures (but not build warnings) for your site on {% data var You can configure a third-party service, such as [Travis CI](https://travis-ci.org/), to display error messages after each commit. 1. If you haven't already, add a file called _Gemfile_ in the root of your publishing source, with the following content: - ``` + ```ruby source `https://rubygems.org` gem `github-pages` ``` 2. Configure your site's repository for the testing service of your choice. For example, to use [Travis CI](https://travis-ci.org/), add a file named _.travis.yml_ in the root of your publishing source, with the following content: - ``` + ```yaml language: ruby rvm: - 2.3 diff --git a/content/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll.md b/content/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll.md index 203b8088ee..8d27177055 100644 --- a/content/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll.md +++ b/content/github/working-with-github-pages/adding-a-theme-to-your-github-pages-site-using-jekyll.md @@ -42,7 +42,7 @@ People with write permissions for a repository can add a theme to a {% data vari {% data reusables.pages.navigate-publishing-source %} 1. Create a new file called _/assets/css/style.scss_. 2. Add the following content to the top of the file: - ``` + ```scss --- --- diff --git a/content/github/working-with-github-pages/creating-a-custom-404-page-for-your-github-pages-site.md b/content/github/working-with-github-pages/creating-a-custom-404-page-for-your-github-pages-site.md index f5523b51a7..e64b467d98 100644 --- a/content/github/working-with-github-pages/creating-a-custom-404-page-for-your-github-pages-site.md +++ b/content/github/working-with-github-pages/creating-a-custom-404-page-for-your-github-pages-site.md @@ -17,7 +17,7 @@ versions: 3. In the file name field, type `404.html` or `404.md`. ![File name field](/assets/images/help/pages/404-file-name.png) 4. If you named your file `404.md`, add the following YAML front matter to the beginning of the file: - ``` + ```yaml --- permalink: /404.html --- diff --git a/content/github/working-with-github-pages/troubleshooting-jekyll-build-errors-for-github-pages-sites.md b/content/github/working-with-github-pages/troubleshooting-jekyll-build-errors-for-github-pages-sites.md index 3b2bb2212b..22f7e9a648 100644 --- a/content/github/working-with-github-pages/troubleshooting-jekyll-build-errors-for-github-pages-sites.md +++ b/content/github/working-with-github-pages/troubleshooting-jekyll-build-errors-for-github-pages-sites.md @@ -78,7 +78,7 @@ This error means that your code references a symlinked file that does not exist This error means that you used non-Latin characters, like `日本語`, without telling the computer to expect these symbols. To troubleshoot, force UTF-8 encoding by adding the following line to your *_config.yml* file: -``` +```yaml encoding: UTF-8 ``` diff --git a/content/github/writing-on-github/basic-writing-and-formatting-syntax.md b/content/github/writing-on-github/basic-writing-and-formatting-syntax.md index cc409e010f..833bf2592f 100644 --- a/content/github/writing-on-github/basic-writing-and-formatting-syntax.md +++ b/content/github/writing-on-github/basic-writing-and-formatting-syntax.md @@ -13,7 +13,7 @@ versions: To create a heading, add one to six `#` symbols before your heading text. The number of `#` you use will determine the size of the heading. -``` +```markdown # The largest heading ## The second largest heading ###### The smallest heading @@ -37,7 +37,7 @@ You can indicate emphasis with bold, italic, or strikethrough text. You can quote text with a `>`. -``` +```markdown In the words of Abraham Lincoln: > Pardon my French @@ -55,7 +55,7 @@ In the words of Abraham Lincoln: You can call out code or a command within a sentence with single backticks. The text within the backticks will not be formatted. -``` +```markdown Use `git status` to list all new or modified files that haven't yet been committed. ``` @@ -102,7 +102,7 @@ You can create an inline link by wrapping link text in brackets `[ ]`, and then You can make an unordered list by preceding one or more lines of text with `-` or `*`. -``` +```markdown - George Washington - John Adams - Thomas Jefferson @@ -112,7 +112,7 @@ You can make an unordered list by preceding one or more lines of text with `-` o To order your list, precede each line with a number. -``` +```markdown 1. James Madison 2. James Monroe 3. John Quincy Adams @@ -126,7 +126,7 @@ You can create a nested list by indenting one or more list items below another i To create a nested list using the web editor on {% data variables.product.product_name %} or a text editor that uses a monospaced font, like [Atom](https://atom.io/), you can align your list visually. Type space characters in front of your nested list item, until the list marker character (`-` or `*`) lies directly below the first character of the text in the item above it. -``` +```markdown 1. First list item - First nested list item - Second nested list item @@ -140,7 +140,7 @@ To create a nested list in the comment editor on {% data variables.product.produ In this example, you could add a nested list item under the list item `100. First list item` by indenting the nested list item a minimum of five spaces, since there are five characters (`100. `) before `First list item`. -``` +```markdown 100. First list item - First nested list item ``` @@ -149,7 +149,7 @@ In this example, you could add a nested list item under the list item `100. Firs You can create multiple levels of nested lists using the same method. For example, because the first nested list item has seven spaces (`␣␣␣␣␣-␣`) before the nested list content `First nested list item`, you would need to indent the second nested list item by seven spaces. -``` +```markdown 100. First list item - First nested list item - Second nested list item diff --git a/content/github/writing-on-github/organizing-information-with-tables.md b/content/github/writing-on-github/organizing-information-with-tables.md index 07a84b6ad6..aad54f147a 100644 --- a/content/github/writing-on-github/organizing-information-with-tables.md +++ b/content/github/writing-on-github/organizing-information-with-tables.md @@ -13,7 +13,7 @@ versions: You can create tables with pipes `|` and hyphens `-`. Hyphens are used to create each column's header, while pipes separate each column. You must include a blank line before your table in order for it to correctly render. -``` +```markdown | First Header | Second Header | | ------------- | ------------- | @@ -27,7 +27,7 @@ The pipes on either end of the table are optional. Cells can vary in width and do not need to be perfectly aligned within columns. There must be at least three hyphens in each column of the header row. -``` +```markdown | Command | Description | | --- | --- | | git status | List all new or modified files | @@ -40,7 +40,7 @@ Cells can vary in width and do not need to be perfectly aligned within columns. You can use [formatting](/articles/basic-writing-and-formatting-syntax) such as links, inline code blocks, and text styling within your table: -``` +```markdown | Command | Description | | --- | --- | | `git status` | List all *new or modified* files | @@ -51,7 +51,7 @@ You can use [formatting](/articles/basic-writing-and-formatting-syntax) such as You can align text to the left, right, or center of a column by including colons `:` to the left, right, or on both sides of the hyphens within the header row. -``` +```markdown | Left-aligned | Center-aligned | Right-aligned | | :--- | :---: | ---: | | git status | git status | git status | @@ -62,7 +62,7 @@ You can align text to the left, right, or center of a column by including colons To include a pipe `|` as content within your cell, use a `\` before the pipe: -``` +```markdown | Name | Character | | --- | --- | | Backtick | ` | diff --git a/content/graphql/guides/introduction-to-graphql.md b/content/graphql/guides/introduction-to-graphql.md index af85a0c39d..542305f7ca 100644 --- a/content/graphql/guides/introduction-to-graphql.md +++ b/content/graphql/guides/introduction-to-graphql.md @@ -81,9 +81,25 @@ GraphQL is [introspective](https://graphql.github.io/learn/introspection/). This * Query `__schema` to list all types defined in the schema and get details about each: ```graphql -query { - __schema { - types { + query { + __schema { + types { + name + kind + description + fields { + name + } + } + } + } + ``` + +* Query `__type` to get details about any type: + + ```graphql + query { + __type(name: "Repository") { name kind description @@ -92,22 +108,6 @@ query { } } } -} - ``` - -* Query `__type` to get details about any type: - - ```graphql -query { - __type(name: "Repository") { - name - kind - description - fields { - name - } - } -} ``` * You can also run an _introspection query_ of the schema via a `GET` request: diff --git a/content/insights/installing-and-configuring-github-insights/enabling-a-link-between-github-insights-and-github-enterprise.md b/content/insights/installing-and-configuring-github-insights/enabling-a-link-between-github-insights-and-github-enterprise.md index 16322a6f83..1a459b1fe1 100644 --- a/content/insights/installing-and-configuring-github-insights/enabling-a-link-between-github-insights-and-github-enterprise.md +++ b/content/insights/installing-and-configuring-github-insights/enabling-a-link-between-github-insights-and-github-enterprise.md @@ -14,7 +14,7 @@ After you enable the link, each user can navigate directly from {% data variable 1. Connect to the administrative shell for {% data variables.product.prodname_ghe_server %}. For more information, see "[Accessing the administrative shell (SSH)](/enterprise/{{ currentVersion }}/admin/guides/installation/accessing-the-administrative-shell-ssh/)." 2. Run the following command. - ``` + ```shell ghe-config 'app.github.insights-available' 'true' && ghe-config-apply ``` 3. Return to {% data variables.product.prodname_ghe_server %}. diff --git a/content/packages/guides/configuring-apache-maven-for-use-with-github-packages.md b/content/packages/guides/configuring-apache-maven-for-use-with-github-packages.md index 62ffeb833c..802d3b7db8 100644 --- a/content/packages/guides/configuring-apache-maven-for-use-with-github-packages.md +++ b/content/packages/guides/configuring-apache-maven-for-use-with-github-packages.md @@ -38,7 +38,7 @@ If you want to interact with multiple repositories, you can add each repository If your instance has subdomain isolation enabled: {% endif %} -``` +```xml "ssh://{% if currentVersion == "free-pro-team@latest" %}github.com{% else %}HOSTNAME{% endif %}/OWNER/REPOSITORY" } ``` @@ -119,7 +119,7 @@ You can use gems from {% data variables.product.prodname_registry %} much like y {% data reusables.package_registry.authenticate-step %} 2. For Bundler, add your {% data variables.product.prodname_dotcom %} user or organization as a source in your *Gemfile* to fetch gems from this new source. For example, you can add a new `source` block to your *Gemfile* that uses {% data variables.product.prodname_registry %} only for the packages you specify, replacing *GEM NAME* with the package you want to install from {% data variables.product.prodname_registry %} and *OWNER* with the user or organization that owns the repository containing the gem you want to install.{% if enterpriseServerVersions contains currentVersion %} Replace `REGISTRY-URL` with the URL for your instance's Rubygems registry. If your instance has subdomain isolation enabled, use `rubygems.HOSTNAME`. If your instance has subdomain isolation disabled, use `HOSTNAME/_registry/rubygems`. In either case, replace *HOSTNAME* with the host name of your {% data variables.product.prodname_ghe_server %} instance.{% endif %} - ``` + ```ruby source "https://rubygems.org" gem "rails" @@ -131,7 +131,7 @@ You can use gems from {% data variables.product.prodname_registry %} much like y 3. For Bundler versions earlier than 1.7.0, you need to add a new global `source`. For more information on using Bundler, see the [bundler.io documentation](http://bundler.io/v1.5/gemfile.html). - ``` + ```ruby source "https://{% if currentVersion == "free-pro-team@latest" %}rubygems.pkg.github.com{% else %}REGISTRY-URL{% endif %}/OWNER" source "https://rubygems.org" diff --git a/content/packages/manage-packages/deleting-a-package.md b/content/packages/manage-packages/deleting-a-package.md index b820d5f65a..b5aef1144a 100644 --- a/content/packages/manage-packages/deleting-a-package.md +++ b/content/packages/manage-packages/deleting-a-package.md @@ -58,7 +58,7 @@ Use the `deletePackageVersion` mutation in the GraphQL API. You must use a token Here is an example cURL command to delete a package version with the package version ID of `MDIyOlJlZ2lzdHJ5UGFja2FnZVZlcnNpb243MTExNg`, using a personal access token. {% if currentVersion == "free-pro-team@latest" %} -``` +```shell curl -X POST \ -H "Accept: application/vnd.github.package-deletes-preview+json" \ -H "Authorization: bearer TOKEN" \ @@ -68,7 +68,7 @@ https://api.github.com/graphql {% else %} -``` +```shell curl -X POST \ -H "Accept: application/vnd.github.package-deletes-preview+json" \ -H "Authorization: bearer TOKEN" \ From 33d79ce81458391dd0e97a6db47a356ff1cfceb2 Mon Sep 17 00:00:00 2001 From: mchammer01 <42146119+mchammer01@users.noreply.github.com> Date: Mon, 18 Jan 2021 12:09:10 +0000 Subject: [PATCH 63/65] address review comment --- .../repository-permission-levels-for-an-organization.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md index cb8e0667dd..e820dda88c 100644 --- a/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md +++ b/content/github/setting-up-and-managing-organizations-and-teams/repository-permission-levels-for-an-organization.md @@ -133,7 +133,7 @@ In addition to managing organization-level settings, organization owners have ad {% if currentVersion == "free-pro-team@latest" or currentVersion ver_gt "enterprise-server@2.21" %} #### Permission requirements for security features -In this section, you can find the repository permission levels required for {% data variables.product.prodname_dependabot %} and {% data variables.product.prodname_advanced_security %} features. +In this section, you can find the repository permission levels required for security features, such as {% data variables.product.prodname_dependabot %} and {% data variables.product.prodname_advanced_security %} features. | Repository action | Read | Triage | Write | Maintain | Admin | |:---|:---:|:---:|:---:|:---:|:---:|{% if currentVersion == "free-pro-team@latest" %} From b46da8dfc7e740472b8852d53745871471ea45b6 Mon Sep 17 00:00:00 2001 From: Vanessa Yuen <6842965+vanessayuenn@users.noreply.github.com> Date: Mon, 18 Jan 2021 13:23:23 +0100 Subject: [PATCH 64/65] Sublanding page all guides section (#16869) * get link liquid tag to accept variables as param * new liquid tag `link_as_article_card` * refactor link liquid tag slightly so we can control what props get rendered * generalize filterCodeExample to use in all guides section * pass in `js-filter-card-max` instead of hardcode max * tweaks and add `data` to CSP for images * add liquid tag tests * add some browser tests for card filters * we still need to rely on `getPathWithLanguage` for hrefs that already have the language code embedded Co-authored-by: Emily Gould <4822039+emilyistoofunky@users.noreply.github.com> --- ...ing-to-amazon-elastic-container-service.md | 1 + .../guides/deploying-to-azure-app-service.md | 3 +- .../deploying-to-google-kubernetes-engine.md | 21 +-- content/actions/index.md | 4 +- content/discussions/index.md | 2 +- data/ui.yml | 8 +- includes/article-cards.html | 43 ++++++ .../liquid-tags/link-as-article-card.html | 7 + javascripts/filter-cards.js | 144 +++++++++++------- javascripts/show-more.js | 2 +- layouts/product-sublanding.html | 10 +- lib/get-link-data.js | 10 +- lib/liquid-tags/link-as-article-card.js | 10 ++ lib/liquid-tags/link.js | 40 +++-- lib/page.js | 2 +- lib/render-content/index.js | 1 + middleware/csp.js | 1 + tests/browser/browser.js | 50 ++++++ tests/unit/liquid-helpers.js | 23 +++ tests/unit/page.js | 2 +- 20 files changed, 287 insertions(+), 97 deletions(-) create mode 100644 includes/article-cards.html create mode 100644 includes/liquid-tags/link-as-article-card.html create mode 100644 lib/liquid-tags/link-as-article-card.js diff --git a/content/actions/guides/deploying-to-amazon-elastic-container-service.md b/content/actions/guides/deploying-to-amazon-elastic-container-service.md index 59b5b7bae2..023472a4cb 100644 --- a/content/actions/guides/deploying-to-amazon-elastic-container-service.md +++ b/content/actions/guides/deploying-to-amazon-elastic-container-service.md @@ -5,6 +5,7 @@ product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} diff --git a/content/actions/guides/deploying-to-azure-app-service.md b/content/actions/guides/deploying-to-azure-app-service.md index 3471b333ac..ef83e1b85a 100644 --- a/content/actions/guides/deploying-to-azure-app-service.md +++ b/content/actions/guides/deploying-to-azure-app-service.md @@ -5,6 +5,7 @@ product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} @@ -54,7 +55,7 @@ Before creating your {% data variables.product.prodname_actions %} workflow, you 3. Configure an Azure publish profile and create an `AZURE_WEBAPP_PUBLISH_PROFILE` secret. - Generate your Azure deployment credentials using a publish profile. For more information, see "[Generate deployment credentials](https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials)" in the Azure documentation. + Generate your Azure deployment credentials using a publish profile. For more information, see "[Generate deployment credentials](https://docs.microsoft.com/en-us/azure/app-service/deploy-github-actions?tabs=applevel#generate-deployment-credentials)" in the Azure documentation. In your {% data variables.product.prodname_dotcom %} repository, create a secret named `AZURE_WEBAPP_PUBLISH_PROFILE` that contains the contents of the publish profile. For more information on creating secrets, see "[Encrypted secrets](/actions/reference/encrypted-secrets#creating-encrypted-secrets-for-a-repository)." diff --git a/content/actions/guides/deploying-to-google-kubernetes-engine.md b/content/actions/guides/deploying-to-google-kubernetes-engine.md index ed8256ebbf..325e0eedad 100644 --- a/content/actions/guides/deploying-to-google-kubernetes-engine.md +++ b/content/actions/guides/deploying-to-google-kubernetes-engine.md @@ -5,6 +5,7 @@ product: '{% data reusables.gated-features.actions %}' versions: free-pro-team: '*' enterprise-server: '>=2.22' +type: 'tutorial' --- {% data reusables.actions.enterprise-beta %} @@ -99,37 +100,37 @@ The following example workflow demonstrates how to build a container image and p {% raw %} ```yaml{:copy} name: Build and Deploy to GKE - + on: release: types: [created] - + env: PROJECT_ID: ${{ secrets.GKE_PROJECT }} GKE_CLUSTER: cluster-1 # Add your cluster name here. GKE_ZONE: us-central1-c # Add your cluster zone here. DEPLOYMENT_NAME: gke-test # Add your deployment name here. IMAGE: static-site - + jobs: setup-build-publish-deploy: name: Setup, Build, Publish, and Deploy runs-on: ubuntu-latest steps: - + - name: Checkout uses: actions/checkout@v2 - + # Setup gcloud CLI - uses: google-github-actions/setup-gcloud@v0.2.0 with: service_account_key: ${{ secrets.GKE_SA_KEY }} project_id: ${{ secrets.GKE_PROJECT }} - + # Configure docker to use the gcloud command-line tool as a credential helper - run: |- gcloud --quiet auth configure-docker - + # Get the GKE credentials so we can deploy to the cluster - uses: google-github-actions/get-gke-credentials@v0.2.1 with: @@ -145,18 +146,18 @@ jobs: --build-arg GITHUB_SHA="$GITHUB_SHA" \ --build-arg GITHUB_REF="$GITHUB_REF" \ . - + # Push the Docker image to Google Container Registry - name: Publish run: |- docker push "gcr.io/$PROJECT_ID/$IMAGE:$GITHUB_SHA" - + # Set up kustomize - name: Set up Kustomize run: |- curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v3.1.0/kustomize_3.1.0_linux_amd64 chmod u+x ./kustomize - + # Deploy the Docker image to the GKE cluster - name: Deploy run: |- diff --git a/content/actions/index.md b/content/actions/index.md index 593b3f462c..75e30f185f 100644 --- a/content/actions/index.md +++ b/content/actions/index.md @@ -36,7 +36,7 @@ changelog: href: https://github.blog/changelog/2020-10-29-github-actions-ubuntu-latest-workflows-will-use-ubuntu-20-04 product_video: https://www.youtube-nocookie.com/embed/cP0I9w2coGU - + redirect_from: - /articles/automating-your-workflow-with-github-actions/ - /articles/customizing-your-project-with-github-actions/ @@ -72,7 +72,7 @@ versions: {% render 'code-example-card' for actionsCodeExamples as example %} - +
    {% octicon "search" width="24" %}
    diff --git a/content/discussions/index.md b/content/discussions/index.md index 66dca4f270..902d7f2a00 100644 --- a/content/discussions/index.md +++ b/content/discussions/index.md @@ -43,7 +43,7 @@ versions: {% render 'discussions-community-card' for discussionsCommunityExamples as example %}
    {% if discussionsCommunityExamples.length > 6 %} - + {% endif %}
    {% octicon "search" width="24" %}
    diff --git a/data/ui.yml b/data/ui.yml index 3644182c6e..769025e23f 100644 --- a/data/ui.yml +++ b/data/ui.yml @@ -148,7 +148,13 @@ product_sublanding: learning_paths: Learning paths learning_paths_desc: Learning paths are a collection of guides that help you master a particular subject. more_guides: more guides - guideTypes: + load_more: Load more guides + all_guides: All Guides + no_result: Sorry, there is no guide that match your filter. + filters: + type: Type + all: All + guide_types: overview: Overview quick_start: Quickstart tutorial: Tutorial diff --git a/includes/article-cards.html b/includes/article-cards.html new file mode 100644 index 0000000000..72b21648ac --- /dev/null +++ b/includes/article-cards.html @@ -0,0 +1,43 @@ +{% assign currentCategory = siteTree[currentLanguage][currentVersion].products[currentProduct].categories[breadcrumbs.category.href] %} + +{% assign maxArticles = 9 %} + +
    +

    {% data ui.product_sublanding.all_guides %}

    + + + + + + + +
    + {% for article in currentCategory.articles %} + + {% assign card_display_class = "" %} + {% if forloop.index > maxArticles %} + {% assign card_display_class = "d-none" %} + {% endif %} + + {% capture link_card %} + {% link_as_article_card {{ article[1].href }} %} + {% endcapture %} + + {{ link_card | replace: "", card_display_class }} + {% endfor %} + + + +
    +

    {% data ui.product_sublanding.no_result %}

    +
    +
    +
    \ No newline at end of file diff --git a/includes/liquid-tags/link-as-article-card.html b/includes/liquid-tags/link-as-article-card.html new file mode 100644 index 0000000000..555cf1e0e2 --- /dev/null +++ b/includes/liquid-tags/link-as-article-card.html @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/javascripts/filter-cards.js b/javascripts/filter-cards.js index 986322b7ae..52280a2933 100644 --- a/javascripts/filter-cards.js +++ b/javascripts/filter-cards.js @@ -1,72 +1,104 @@ -function filterCards (cards, value) { - const noResults = document.querySelector('.js-filter-card-no-results') - const matchReg = new RegExp(value, 'i') - - // Track whether or not we had at least one match - let hasMatches = false - - for (let index = 0; index < cards.length; index++) { - const card = cards[index] - - // Filter was emptied - if (!value) { - // Make sure we don't show the "No results" blurb - hasMatches = true - - // Hide all but the first 6 - if (index > 5) { - card.classList.add('d-none') - } else { - card.classList.remove('d-none') - } - - continue - } - - // Check if this card matches - any `data-*` attribute contains the string - const cardMatches = Object.keys(card.dataset) - .some(key => matchReg.test(card.dataset[key])) - - if (cardMatches) { - card.classList.remove('d-none') - hasMatches = true - } else { - card.classList.add('d-none') - } - } - - // If there wasn't at least one match, show the "no results" text - if (!hasMatches) { - document.querySelector('.js-filter-card-value').textContent = value - noResults.classList.remove('d-none') - } else { - noResults.classList.add('d-none') - } +function matchCardBySearch (card, searchString) { + const matchReg = new RegExp(searchString, 'i') + // Check if this card matches - any `data-*` attribute contains the string + return Object.keys(card.dataset).some(key => matchReg.test(card.dataset[key])) } -export default function filterCodeExamples () { - const filter = document.querySelector('.js-filter-card-filter') +function matchCardByAttribute (card, attribute, value) { + if (attribute in card.dataset) { + return card.dataset[attribute] === value + } + return false +} + +export default function cardsFilter () { + const inputFilter = document.querySelector('.js-filter-card-filter') + const dropdownFilter = document.querySelector('.js-filter-card-filter-dropdown') const cards = Array.from(document.querySelectorAll('.js-filter-card')) const showMoreButton = document.querySelector('.js-filter-card-show-more') + const noResults = document.querySelector('.js-filter-card-no-results') + // if jsFilterCardMax not set, assume no limit (well, at 99) + const maxCards = showMoreButton ? parseInt(showMoreButton.dataset.jsFilterCardMax || 99) : null - if (filter) { - filter.addEventListener('keyup', evt => { - const value = evt.currentTarget.value + const filterEventHandler = (evt) => { + const { currentTarget } = evt + const value = currentTarget.value - // Show or hide the "Show more" button if there is a value - if (value) showMoreButton.classList.add('d-none') - else showMoreButton.classList.remove('d-none') + // Show or hide the "Show more" button if there is a value + if (value) { + showMoreButton.classList.add('d-none') + } else { + showMoreButton.classList.remove('d-none') + } - filterCards(cards, value) + // Track whether or not we had at least one match + let hasMatches = false + + for (let index = 0; index < cards.length; index++) { + const card = cards[index] + + // Filter was emptied + if (!value) { + // Make sure we don't show the "No results" blurb + hasMatches = true + + // Hide all but the first n number of cards + if (index > maxCards - 1) { + card.classList.add('d-none') + } else { + card.classList.remove('d-none') + } + + continue + } + + let cardMatches = false + + if (currentTarget.tagName === 'INPUT') { + cardMatches = matchCardBySearch(card, value) + } + + if (currentTarget.tagName === 'SELECT' && currentTarget.name) { + cardMatches = matchCardByAttribute(card, currentTarget.name, value) + } + + if (cardMatches) { + card.classList.remove('d-none') + hasMatches = true + } else { + card.classList.add('d-none') + } + } + + // If there wasn't at least one match, show the "no results" text + if (!hasMatches) { + noResults.classList.remove('d-none') + } else { + noResults.classList.add('d-none') + } + + return hasMatches + } + + if (inputFilter) { + inputFilter.addEventListener('keyup', (evt) => { + const hasMatches = filterEventHandler(evt) + if (!hasMatches) { + document.querySelector('.js-filter-card-value').textContent = evt.currentTarget.value + } }) } + if (dropdownFilter) { + dropdownFilter.addEventListener('change', filterEventHandler) + } + if (showMoreButton) { showMoreButton.addEventListener('click', evt => { // Number of cards that are currently visible const numShown = cards.filter(card => !card.classList.contains('d-none')).length - // We want to show 6 more - const totalToShow = numShown + 6 + // We want to show n more cards + const totalToShow = numShown + maxCards for (let index = numShown; index < cards.length; index++) { const card = cards[index] @@ -83,7 +115,7 @@ export default function filterCodeExamples () { // They're all shown now, we should hide the button if (totalToShow >= cards.length) { - evt.currentTarget.style.display = 'none' + evt.currentTarget.classList.add('d-none') } }) } diff --git a/javascripts/show-more.js b/javascripts/show-more.js index 00a23bba81..d67ef4d362 100644 --- a/javascripts/show-more.js +++ b/javascripts/show-more.js @@ -1,5 +1,5 @@ /* - * This utility makes it easy to implement a list of items, some of which are hidden initially + * This utility component implement a list of items, some of which are hidden initially * until user clicks "show more". * * Example: diff --git a/layouts/product-sublanding.html b/layouts/product-sublanding.html index 92b67c4429..d9af6ab059 100644 --- a/layouts/product-sublanding.html +++ b/layouts/product-sublanding.html @@ -1,5 +1,5 @@ -{% assign guideTypes = site.data.ui.product_sublanding.guideTypes %} +{% assign guideTypes = site.data.ui.product_sublanding.guide_types %} {% include head %} @@ -42,7 +42,7 @@
    {{ forloop.index }}
    -
    {{ guideTypes[guide.type] }}
    +
    {{ guideTypes[guide.page.type] }}

    {{ guide.title }}

    {{ guide.intro }}
    @@ -87,7 +87,7 @@ {{ forloop.index }}

    {{ guide.title }}

    -
    {{ guideTypes[guide.type] }}
    +
    {{ guideTypes[guide.page.type] }}
    {% endfor %} @@ -106,9 +106,7 @@
    -
    - -
    + {% include 'article-cards' %}
    diff --git a/lib/get-link-data.js b/lib/get-link-data.js index 0d7a078d0a..46a64d7730 100644 --- a/lib/get-link-data.js +++ b/lib/get-link-data.js @@ -5,7 +5,7 @@ const removeFPTFromPath = require('./remove-fpt-from-path') // rawLinks is an array of paths: [ '/foo' ] // we need to convert it to an array of localized objects: [ { href: '/en/foo', title: 'Foo', intro: 'Description here' } ] -module.exports = async (rawLinks, context, additionalProperties = []) => { +module.exports = async (rawLinks, context) => { if (!rawLinks) return const links = [] @@ -20,17 +20,11 @@ module.exports = async (rawLinks, context, additionalProperties = []) => { const opts = { textOnly: true, encodeEntities: true } - const props = {} - for (const propName of additionalProperties) { - props[propName] = linkedPage[propName] - } - links.push({ href, title: await linkedPage.renderTitle(context, opts), intro: await linkedPage.renderProp('intro', context, opts), - page: linkedPage, - ...props + page: linkedPage }) } diff --git a/lib/liquid-tags/link-as-article-card.js b/lib/liquid-tags/link-as-article-card.js new file mode 100644 index 0000000000..060e3989ee --- /dev/null +++ b/lib/liquid-tags/link-as-article-card.js @@ -0,0 +1,10 @@ +const Link = require('./link') + +// For details, see class method in lib/liquid-tags/link.js +module.exports = class LinkAsArticleCard extends Link { + async renderPageProps (page, ctx, props) { + const renderedProps = await super.renderPageProps(page, ctx, props) + const { type } = page + return { ...renderedProps, type } + } +} diff --git a/lib/liquid-tags/link.js b/lib/liquid-tags/link.js index 5239dc98c5..d82449e2b0 100644 --- a/lib/liquid-tags/link.js +++ b/lib/liquid-tags/link.js @@ -5,6 +5,7 @@ const liquid = new Liquid.Engine() const LiquidTag = require('./liquid-tag') const findPage = require('../find-page') const getApplicableVersions = require('../get-applicable-versions') +const { getPathWithLanguage } = require('../path-utils') // This class supports a set of link tags. Each tag expects one parameter, a language-agnostic href: // @@ -27,7 +28,18 @@ module.exports = class Link extends LiquidTag { super(template, tagName, href.trim()) } - async parseTemplate (context) { + async renderPageProps (page, ctx, props) { + const renderedProps = {} + + for (const propName in props) { + const { opt } = props[propName] || {} + renderedProps[propName] = await page.renderProp(propName, ctx, opt) + } + + return renderedProps + } + + async parseTemplate (context, opts = { shortTitle: false }) { const template = await this.getTemplate() const ctx = context.environments[0] @@ -38,7 +50,16 @@ module.exports = class Link extends LiquidTag { assert(ctx.currentLanguage, 'context.currentLanguage is required') // process any liquid in hrefs (e.g., /enterprise/{{ page.version }}) - const href = await liquid.parseAndRender(this.param, ctx) + let href = await liquid.parseAndRender(this.param, ctx) + + // process variable defined in page scope + if (href === '') { + const match = liquidVariableSyntax.exec(this.param) + if (match) { + const variable = new Liquid.Variable(match[1]) + href = await variable.render(context) + } + } let fullPath = href const dirName = path.dirname(ctx.page.relativePath) @@ -52,7 +73,7 @@ module.exports = class Link extends LiquidTag { } // add language code - fullPath = path.join('/', ctx.currentLanguage, fullPath) + fullPath = getPathWithLanguage(fullPath, ctx.currentLanguage) // find the page based on the full path const page = findPage(fullPath, ctx.pages, ctx.redirects) @@ -61,20 +82,21 @@ module.exports = class Link extends LiquidTag { if (!page || (page.hidden && !ctx.page.hidden)) { return '' } - // also return early if the found page should not render in current version if (!getApplicableVersions(page.versions).includes(ctx.currentVersion)) { return '' } // find and render the props - const title = await page.renderProp('title', ctx, { textOnly: true, encodeEntities: true }) + const renderedProps = await this.renderPageProps(page, ctx, { + title: { opt: { textOnly: true, encodeEntities: true } }, + intro: { opt: { unwrap: true } } + }) - // we want markdown in intros to be parsed, so we do not pass textOnly here - const intro = await page.renderProp('intro', ctx, { unwrap: true }) - - const parsed = await liquid.parseAndRender(template, { fullPath, title, intro }) + const parsed = await liquid.parseAndRender(template, { fullPath, ...renderedProps }) return parsed.trim() } } + +const liquidVariableSyntax = RegExp(`^${Liquid.VariableStart.source}\\s*(.*)\\s*${Liquid.VariableEnd.source}`) diff --git a/lib/page.js b/lib/page.js index 3e88491a0d..a7072b7bde 100644 --- a/lib/page.js +++ b/lib/page.js @@ -210,7 +210,7 @@ class Page { learningTracks.push({ title: await renderContent(track.title, context, { textOnly: true, encodeEntities: true }), description: await renderContent(track.description, context, { textOnly: true, encodeEntities: true }), - guides: await getLinkData(track.guides, context, ['type']) + guides: await getLinkData(track.guides, context) }) } this.learningTracks = learningTracks diff --git a/lib/render-content/index.js b/lib/render-content/index.js index 20122bc1eb..3394225894 100644 --- a/lib/render-content/index.js +++ b/lib/render-content/index.js @@ -12,6 +12,7 @@ renderContent.liquid.registerTag('topic_link_in_list', require('../liquid-tags/t renderContent.liquid.registerTag('indented_data_reference', require('../liquid-tags/indented-data-reference')) renderContent.liquid.registerTag('data', require('../liquid-tags/data')) renderContent.liquid.registerTag('octicon', require('../liquid-tags/octicon')) +renderContent.liquid.registerTag('link_as_article_card', require('../liquid-tags/link-as-article-card')) for (const tag in tags) { // Register all the extended markdown tags, like {% note %} and {% warning %} diff --git a/middleware/csp.js b/middleware/csp.js index cbf6119f6e..bd5a3402c2 100644 --- a/middleware/csp.js +++ b/middleware/csp.js @@ -22,6 +22,7 @@ module.exports = async (req, res, next) => { ], imgSrc: [ "'self'", + 'data:', 'github.githubassets.com', 'github-images.s3.amazonaws.com', 'octodex.github.com', diff --git a/tests/browser/browser.js b/tests/browser/browser.js index 597d301b56..956b52f216 100644 --- a/tests/browser/browser.js +++ b/tests/browser/browser.js @@ -249,3 +249,53 @@ describe('platform specific content', () => { } }) }) + +describe('card filters', () => { + it('loads correctly', async () => { + await page.goto('http://localhost:4001/en/actions') + const shownCards = await page.$$('.js-filter-card:not(.d-none)') + const shownNoResult = await page.$('.js-filter-card-no-results:not(.d-none)') + const maxCards = await page.$eval('.js-filter-card-show-more', btn => parseInt(btn.dataset.jsFilterCardMax)) + expect(shownCards.length).toBe(maxCards) + expect(shownNoResult).toBeNull() + }) + + it('filters cards', async () => { + await page.goto('http://localhost:4001/en/actions') + await page.click('input.js-filter-card-filter') + await page.type('input.js-filter-card-filter', 'issues') + const shownCards = await page.$$('.js-filter-card:not(.d-none)') + const showMoreClasses = await page.$eval('.js-filter-card-show-more', btn => Object.values(btn.classList)) + expect(showMoreClasses).toContain('d-none') + expect(shownCards.length).toBeGreaterThan(1) + }) + + it('works with select input', async () => { + await page.goto('http://localhost:4001/en/actions/guides') + await page.select('.js-filter-card-filter-dropdown[name="type"]', 'overview') + const shownCards = await page.$$('.js-filter-card:not(.d-none)') + const shownCardsAttrib = await page.$$eval('.js-filter-card:not(.d-none)', cards => + cards.map(card => card.dataset.type) + ) + shownCardsAttrib.map(attrib => expect(attrib).toBe('overview')) + expect(shownCards.length).toBeGreaterThan(0) + }) + + it('shows more cards', async () => { + await page.goto('http://localhost:4001/en/actions') + const maxCards = await page.$eval('.js-filter-card-show-more', btn => parseInt(btn.dataset.jsFilterCardMax)) + await page.click('.js-filter-card-show-more') + const shownCards = await page.$$('.js-filter-card:not(.d-none)') + expect(shownCards.length).toBe(maxCards * 2) + }) + + it('displays no result message', async () => { + await page.goto('http://localhost:4001/en/actions') + await page.click('input.js-filter-card-filter') + await page.type('input.js-filter-card-filter', 'this should not work') + const shownCards = await page.$$('.js-filter-card:not(.d-none)') + expect(shownCards.length).toBe(0) + const noResultsClasses = await page.$eval('.js-filter-card-no-results', elem => Object.values(elem.classList)) + expect(noResultsClasses).not.toContain('d-none') + }) +}) diff --git a/tests/unit/liquid-helpers.js b/tests/unit/liquid-helpers.js index fdf2073a7b..49509ce72b 100644 --- a/tests/unit/liquid-helpers.js +++ b/tests/unit/liquid-helpers.js @@ -45,6 +45,16 @@ describe('liquid helper tags', () => { const expected = '' const output = await liquid.parseAndRender(template, context) expect(output.includes(expected)).toBe(true) + // set this back to english + context.currentLanguage = 'en' + }) + + test('link tag with local variable', async () => { + const template = `{% assign href = "/contributing-and-collaborating-using-github-desktop" %} + {% link {{ href }} %}` + const expected = '' + const output = await liquid.parseAndRender(template, context) + expect(output.includes(expected)).toBe(true) }) test('link tag with absolute path', async () => { @@ -84,6 +94,19 @@ describe('liquid helper tags', () => { expect(output).toBe(expected) }) + test('link_as_article_card', async () => { + const template = '{% link_as_article_card /contributing-and-collaborating-using-github-desktop %}' + const expected = `` + const output = await liquid.parseAndRender(template, context) + expect(output).toBe(expected) + }) + describe('indented_data_reference tag', () => { test('without any number of spaces specified', async () => { const template = '{% indented_data_reference site.data.reusables.example %}' diff --git a/tests/unit/page.js b/tests/unit/page.js index a2e10a3c6d..d86452f6ad 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -335,7 +335,7 @@ describe('Page class', () => { } } await page.render(context) - expect(getLinkData).toHaveBeenCalledWith(guides, context, ['type']) + expect(getLinkData).toHaveBeenCalledWith(guides, context) expect(page.learningTracks).toHaveLength(2) }) }) From 69f15f1554fa5dd6cd68c6cece027dcce47c35f9 Mon Sep 17 00:00:00 2001 From: Felicity Chapman Date: Tue, 19 Jan 2021 09:20:09 +0000 Subject: [PATCH 65/65] Update content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md --- .../types-of-emails-github-sends.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md b/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md index f6645076ab..48115cd1c3 100644 --- a/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md +++ b/content/github/setting-up-and-managing-your-github-user-account/types-of-emails-github-sends.md @@ -34,7 +34,7 @@ If you've upgraded to paid products or features, then you'll receive billing rec - Usability testing sessions - Previewing early prototypes or concepts -These emails are infrequent and you can choose whether or not to participate. If you're interested in additional opportunities to participate in research sessions, you may add yourself to the [GitHub Customer Research Panel](https://cxr.github.com). +These emails are infrequent and you can choose whether or not to participate. If you're interested in additional opportunities to participate in research sessions, you may add yourself to the GitHub Customer Research Panel. For more information, see "[GitHub Customer Experience Research](https://cxr.github.com)." ### Marketing emails