From da60aa51e1116b245375b793894389f46af5a138 Mon Sep 17 00:00:00 2001 From: Sarah Schneider Date: Thu, 15 Oct 2020 16:20:41 -0400 Subject: [PATCH] Support enterpriseServerVersions in Liquid statements (#16058) * remove outdated and redundant context.enterpriseVersions and add new context.enterpriseServerVersions * update references from context.enterpriseVersions -> context.enterpriseServerReleases * add test * also test oldest supported enterprise version in addition to the latest * Script to update not-free-pro-team conditionals (#16060) * script to update not-free-pro-team conditionals * change string to regex so we can do replace all * remove stray test.only * Update middleware/context.js Co-authored-by: James M. Greene * Update tests/unit/page.js Co-authored-by: James M. Greene * Update tests/unit/page.js Co-authored-by: James M. Greene * Update tests/fixtures/page-versioned-for-all-enterprise-releases.md Co-authored-by: James M. Greene Co-authored-by: James M. Greene --- .../upgrade-requirements.md | 4 +- includes/error-404-deprecation-message.html | 4 +- middleware/context.js | 2 +- .../update-not-fpt-conditionals.js | 77 +++++++++++++++++++ ...e-versioned-for-all-enterprise-releases.md | 19 +++++ tests/unit/page.js | 38 +++++++++ 6 files changed, 139 insertions(+), 5 deletions(-) create mode 100755 script/new-versioning/update-not-fpt-conditionals.js create mode 100644 tests/fixtures/page-versioned-for-all-enterprise-releases.md diff --git a/content/admin/enterprise-management/upgrade-requirements.md b/content/admin/enterprise-management/upgrade-requirements.md index 786731690b7b..6506fdf49084 100644 --- a/content/admin/enterprise-management/upgrade-requirements.md +++ b/content/admin/enterprise-management/upgrade-requirements.md @@ -21,7 +21,7 @@ versions: ### Recommendations -- Include as few upgrades as possible in your upgrade process. For example, instead of upgrading from {% data variables.product.prodname_enterprise %} {{ enterpriseVersions.supported[2] }} to {{ enterpriseVersions.supported[1] }} to {{ enterpriseVersions.latest }}, you could upgrade from {% data variables.product.prodname_enterprise %} {{ enterpriseVersions.supported[2] }} to {{ enterpriseVersions.latest }}. +- Include as few upgrades as possible in your upgrade process. For example, instead of upgrading from {% data variables.product.prodname_enterprise %} {{ enterpriseServerReleases.supported[2] }} to {{ enterpriseServerReleases.supported[1] }} to {{ enterpriseServerReleases.latest }}, you could upgrade from {% data variables.product.prodname_enterprise %} {{ enterpriseServerReleases.supported[2] }} to {{ enterpriseServerReleases.latest }}. - If you’re several versions behind, upgrade {% data variables.product.product_location_enterprise %} as far forward as possible with each step of your upgrade process. Using the latest version possible on each upgrade allows you to take advantage of performance improvements and bug fixes. For example, you could upgrade from {% data variables.product.prodname_enterprise %} 2.7 to 2.8 to 2.10, but upgrading from {% data variables.product.prodname_enterprise %} 2.7 to 2.9 to 2.10 uses a later version in the second step. - Use the latest patch release when upgrading. {% data reusables.enterprise_installation.enterprise-download-upgrade-pkg %} - Use a staging instance to test the upgrade steps. For more information, see "[Setting up a staging instance](/enterprise/{{ currentVersion }}/admin/guides/installation/setting-up-a-staging-instance/)." @@ -29,7 +29,7 @@ versions: ### Requirements -- You must upgrade from a feature release that's **at most** two releases behind. For example, to upgrade to {% data variables.product.prodname_enterprise %} {{ enterpriseVersions.latest }}, you must be on {% data variables.product.prodname_enterprise %} {{ enterpriseVersions.supported[1] }} or {{ enterpriseVersions.supported[2] }}. +- You must upgrade from a feature release that's **at most** two releases behind. For example, to upgrade to {% data variables.product.prodname_enterprise %} {{ enterpriseServerReleases.latest }}, you must be on {% data variables.product.prodname_enterprise %} {{ enterpriseServerReleases.supported[1] }} or {{ enterpriseServerReleases.supported[2] }}. - {% data reusables.enterprise_installation.hotpatching-explanation %} - A hotpatch may require downtime if the affected services (like kernel, MySQL, or Elasticsearch) require a VM reboot or a service restart. You'll be notified when a reboot or restart is required. You can complete the reboot or restart at a later time. - Additional root storage must be available when upgrading through hotpatching, as it installs multiple versions of certain services until the upgrade is complete. Pre-flight checks will notify you if you don't have enough root disk storage. diff --git a/includes/error-404-deprecation-message.html b/includes/error-404-deprecation-message.html index f81bd2d4d03d..977fad83df0c 100644 --- a/includes/error-404-deprecation-message.html +++ b/includes/error-404-deprecation-message.html @@ -1,5 +1,5 @@ -{% if enterpriseVersions.deprecated contains currentVersion %} -{% assign deprecatedDate = enterpriseVersions.dates[currentVersion].deprecationDate %} +{% if enterpriseServerReleases.deprecated contains currentVersion %} +{% assign deprecatedDate = enterpriseServerReleases.dates[currentVersion].deprecationDate %}

diff --git a/middleware/context.js b/middleware/context.js index 37ed754d72d1..ec9915f421f8 100644 --- a/middleware/context.js +++ b/middleware/context.js @@ -34,9 +34,9 @@ module.exports = async function contextualize (req, res, next) { req.context.query = req.query req.context.languages = languages req.context.earlyAccessPaths = earlyAccessPaths - req.context.enterpriseVersions = enterpriseServerReleases req.context.productNames = productNames req.context.enterpriseServerReleases = enterpriseServerReleases + req.context.enterpriseServerVersions = Object.keys(allVersions).filter(version => version.startsWith('enterprise-server@')) req.context.redirects = redirects req.context.site = site[req.language].site req.context.siteTree = siteTree diff --git a/script/new-versioning/update-not-fpt-conditionals.js b/script/new-versioning/update-not-fpt-conditionals.js new file mode 100755 index 000000000000..5ab96ba3aa28 --- /dev/null +++ b/script/new-versioning/update-not-fpt-conditionals.js @@ -0,0 +1,77 @@ +#!/usr/bin/env node + +const fs = require('fs') +const path = require('path') +const walk = require('walk-sync') +const frontmatter = require('@github-docs/frontmatter') +const contentPath = path.join(process.cwd(), 'content') +const dataPath = path.join(process.cwd(), 'data') + +// [start-readme] +// +// Run this script to update these Liquid conditionals: +// +// {% if currentVersion != 'free-pro-team@latest' %} +// +// to: +// +// {% if enterpriseServerVersions contains currentVersion %} +// +// [end-readme] + +// The new conditional to add +const newConditional = 'enterpriseServerVersions contains currentVersion' + +// The old conditional to replace +const oldConditional = /currentVersion != ["']free-pro-team@latest["']/g + +console.log('Working...\n') + +const englishContentFiles = walkContent(contentPath) +const englishDataFiles = walkData(dataPath, englishContentFiles) + +function walkContent (dirPath) { + return walk(dirPath, { includeBasePath: true, directories: false }) + .filter(file => file.includes('/content/')) + .filter(file => file.endsWith('.md')) + .filter(file => !file.endsWith('README.md')) +} + +function walkData (dirPath, contentFiles) { + return walk(dirPath, { includeBasePath: true, directories: false }) + .filter(file => file.includes('/data/reusables') || file.includes('/data/variables')) + .filter(file => !file.endsWith('README.md')) +} + +englishDataFiles + .forEach(file => { + const dataContent = fs.readFileSync(file, 'utf8') + + // Update Liquid in data files + const newDataContent = updateLiquid(dataContent, file) + + fs.writeFileSync(file, newDataContent) + }) + +englishContentFiles + .forEach(file => { + const { data, content } = frontmatter(fs.readFileSync(file, 'utf8')) + + // Update Liquid in content files + const newContent = updateLiquid(content, file) + + // Update Liquid in frontmatter props + Object.keys(data) + .filter(key => typeof data[key] === 'string') + .forEach(key => { + data[key] = updateLiquid(data[key], file) + }) + + fs.writeFileSync(file, frontmatter.stringify(newContent, data, { lineWidth: 10000 })) + }) + +function updateLiquid (content) { + return content.replace(oldConditional, newConditional) +} + +console.log('Done!') diff --git a/tests/fixtures/page-versioned-for-all-enterprise-releases.md b/tests/fixtures/page-versioned-for-all-enterprise-releases.md new file mode 100644 index 000000000000..cd2311661fd1 --- /dev/null +++ b/tests/fixtures/page-versioned-for-all-enterprise-releases.md @@ -0,0 +1,19 @@ +--- +title: Page versioned for all Enterprise releases +versions: + free-pro-team: '*' + enterprise-server: '*' +--- + +{% if currentVersion == 'free-pro-team@latest' %} + +This text should only render on non-Enterprise + +{% endif %} + + +{% if enterpriseServerVersions contains currentVersion %} + +This text should render on any actively supported version of Enterprise Server + +{% endif %} diff --git a/tests/unit/page.js b/tests/unit/page.js index 669e5ef2496f..5b3da5a5dd1a 100644 --- a/tests/unit/page.js +++ b/tests/unit/page.js @@ -1,6 +1,7 @@ const path = require('path') const cheerio = require('cheerio') const Page = require('../../lib/page') +const allVersionIds = Object.keys(require('../../lib/all-versions')) const enterpriseServerReleases = require('../../lib/enterprise-server-releases') const nonEnterpriseDefaultVersion = require('../../lib/non-enterprise-default-version') // get the `free-pro-team` segment of `free-pro-team@latest` @@ -121,6 +122,43 @@ describe('Page class', () => { const $ = cheerio.load(rendered) expect($('a[href="/capistrano"]').length).toBe(1) }) + + // Most of our Liquid versioning tests are in https://github.com/docs/render-content, + // But they don't have access to our currently supported versions, which we're testing here. + // This test ensures that this works as expected: {% if enterpriseServerVersions contains currentVersion %} + test('renders the expected Enterprise Server versioned content', async () => { + const page = new Page({ + relativePath: 'page-versioned-for-all-enterprise-releases.md', + basePath: path.join(__dirname, '../fixtures'), + languageCode: 'en' + }) + // set version to the latest enteprise version + const context = { + currentVersion: `enterprise-server@${enterpriseServerReleases.latest}`, + currentLanguage: 'en', + enterpriseServerVersions: allVersionIds.filter(id => id.startsWith('enterprise-server@')) + } + let rendered = await page.render(context) + let $ = cheerio.load(rendered) + expect($.text()).toBe('This text should render on any actively supported version of Enterprise Server') + expect($.text()).not.toBe('This text should only render on non-Enterprise') + + // change version to the oldest enterprise version, re-render, and test again; + // the results should be the same + context.currentVersion = `enterprise-server@${enterpriseServerReleases.oldestSupported}` + rendered = await page.render(context) + $ = cheerio.load(rendered) + expect($.text()).toBe('This text should render on any actively supported version of Enterprise Server') + expect($.text()).not.toBe('This text should only render on non-Enterprise') + + // change version to non-enterprise, re-render, and test again; + // the results should be the opposite + context.currentVersion = nonEnterpriseDefaultVersion + rendered = await page.render(context) + $ = cheerio.load(rendered) + expect($.text()).not.toBe('This text should render on any actively supported version of Enterprise Server') + expect($.text()).toBe('This text should only render on non-Enterprise') + }) }) test('preserves `languageCode`', () => {