From f713e5985b4c11cfc616fb8a8cfd8ea46f53f408 Mon Sep 17 00:00:00 2001 From: GatsbyJS Bot Date: Wed, 22 Nov 2023 06:04:15 -0500 Subject: [PATCH] fix: re-install lmdb when detecting the absence of @LMDB prebuilt packages (#38691) (#38707) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: re-install lmdb when detecting the absence of @lmdb prebuilt packages * chore: set the correct root lmdb and add further comments * chore: linter * chore: linting * chore: make the install check for reliable and install @lmdb instead of lmdb * fix: no need to touch the patch, we can leverage the force binary flag * chore: add integration test for lmdb fix * chore: add CCI config for new integration test * add integration_tests_esm_in_gatsby_files to jobs * fix: integration test for lmdb-regeneration * fix: cli path in test * chore: actually add lmdb's dist directory * fix: back to the npmrc and just rm -rf @lmdb modules --------- Co-authored-by: Michal Piechowiak (cherry picked from commit e3365ab01eebb6c17bbae7fcb7e74040a0c4f260) Co-authored-by: João Antunes --- .circleci/config.yml | 9 ++ .../lmdb-regeneration/.gitignore | 3 + integration-tests/lmdb-regeneration/.npmrc | 1 + integration-tests/lmdb-regeneration/LICENSE | 21 ++++ integration-tests/lmdb-regeneration/README.md | 3 + .../lmdb-regeneration/__tests__/index.js | 59 ++++++++++ .../lmdb-regeneration/gatsby-config.js | 9 ++ .../lmdb-regeneration/jest.config.js | 3 + .../lmdb-regeneration/package.json | 22 ++++ .../lmdb-regeneration/src/images/icon.png | Bin 0 -> 11189 bytes .../lmdb-regeneration/src/pages/404.jsx | 49 ++++++++ .../lmdb-regeneration/src/pages/test-dsg.jsx | 17 +++ .../schema/graphql-engine/bundle-webpack.ts | 106 +++++++++++++++++- 13 files changed, 299 insertions(+), 3 deletions(-) create mode 100644 integration-tests/lmdb-regeneration/.gitignore create mode 100644 integration-tests/lmdb-regeneration/.npmrc create mode 100644 integration-tests/lmdb-regeneration/LICENSE create mode 100644 integration-tests/lmdb-regeneration/README.md create mode 100644 integration-tests/lmdb-regeneration/__tests__/index.js create mode 100644 integration-tests/lmdb-regeneration/gatsby-config.js create mode 100644 integration-tests/lmdb-regeneration/jest.config.js create mode 100644 integration-tests/lmdb-regeneration/package.json create mode 100644 integration-tests/lmdb-regeneration/src/images/icon.png create mode 100644 integration-tests/lmdb-regeneration/src/pages/404.jsx create mode 100644 integration-tests/lmdb-regeneration/src/pages/test-dsg.jsx diff --git a/.circleci/config.yml b/.circleci/config.yml index 2af8a75829f42..e17a153324ebc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -313,6 +313,13 @@ jobs: test_path: integration-tests/esm-in-gatsby-files test_command: yarn test + integration_tests_lmdb_regeneration: + executor: node + steps: + - e2e-test: + test_path: integration-tests/lmdb-regeneration + test_command: yarn test + e2e_tests_path-prefix: <<: *e2e-executor steps: @@ -590,6 +597,8 @@ workflows: <<: *e2e-test-workflow - integration_tests_esm_in_gatsby_files: <<: *e2e-test-workflow + - integration_tests_lmdb_regeneration: + <<: *e2e-test-workflow - integration_tests_gatsby_cli: requires: - bootstrap diff --git a/integration-tests/lmdb-regeneration/.gitignore b/integration-tests/lmdb-regeneration/.gitignore new file mode 100644 index 0000000000000..f9fd0a59de1f5 --- /dev/null +++ b/integration-tests/lmdb-regeneration/.gitignore @@ -0,0 +1,3 @@ +__tests__/__debug__ +node_modules +yarn.lock diff --git a/integration-tests/lmdb-regeneration/.npmrc b/integration-tests/lmdb-regeneration/.npmrc new file mode 100644 index 0000000000000..1a456a8d1c769 --- /dev/null +++ b/integration-tests/lmdb-regeneration/.npmrc @@ -0,0 +1 @@ +build_from_source=true diff --git a/integration-tests/lmdb-regeneration/LICENSE b/integration-tests/lmdb-regeneration/LICENSE new file mode 100644 index 0000000000000..20f91f2b3c52b --- /dev/null +++ b/integration-tests/lmdb-regeneration/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 gatsbyjs + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/integration-tests/lmdb-regeneration/README.md b/integration-tests/lmdb-regeneration/README.md new file mode 100644 index 0000000000000..8df148ba4dc0d --- /dev/null +++ b/integration-tests/lmdb-regeneration/README.md @@ -0,0 +1,3 @@ +## Artifacts test suite + +This integration test suite helps us assert our mechanism to heal back from a broken lmdb installation is working by validating we install and use the correct prebundled binary for our platform diff --git a/integration-tests/lmdb-regeneration/__tests__/index.js b/integration-tests/lmdb-regeneration/__tests__/index.js new file mode 100644 index 0000000000000..3da14d6ce0d54 --- /dev/null +++ b/integration-tests/lmdb-regeneration/__tests__/index.js @@ -0,0 +1,59 @@ +const path = require(`path`) +const execa = require(`execa`) +const mod = require("module") +const fs = require(`fs-extra`) + +jest.setTimeout(100000) + +const rootPath = path.resolve(__dirname, "../") + +describe(`Lmdb regeneration`, () => { + test(`gatbsy build detects lmdb setup built from source and installs pre-buit package`, async () => { + const lmdbNodeModulesPath = path.resolve(rootPath, "node_modules", "lmdb") + // Make sure we clear out the current `@lmdb` optional dependencies + const pathsToRemove = [ + path.resolve(rootPath, "node_modules", "@lmdb"), + path.resolve(rootPath, "node_modules", "gatsby", "node_modules", "@lmdb"), + ] + for (let path of pathsToRemove) { + fs.rmSync(path, { force: true, recursive: true }) + } + // Check the lmdb instance we have installed does have a binary built from source since we need it to reproduce the fix we're trying to test + // If this check fails then it means our fixture is wrong and we're relying on an lmdb instance with prebuilt binaries + const builtFromSource = fs.existsSync( + path.resolve(lmdbNodeModulesPath, "build", "Release", "lmdb.node") + ) + expect(builtFromSource).toEqual(true) + + const options = { + stderr: `inherit`, + stdout: `inherit`, + cwd: rootPath, + } + const gatsbyBin = path.resolve(rootPath, `node_modules`, `gatsby`, `cli.js`) + await execa(gatsbyBin, [`build`], options) + + // lmdb module with prebuilt binaries for our platform + const lmdbPackage = `@lmdb/lmdb-${process.platform}-${process.arch}` + + // If the fix worked correctly we should have installed the prebuilt binary for our platform under our `.cache` directory + const lmdbRequire = mod.createRequire( + path.resolve(rootPath, ".cache", "internal-packages", "package.json") + ) + expect(() => { + lmdbRequire.resolve(lmdbPackage) + }).not.toThrow() + + // The resulting query-engine bundle should not contain the binary built from source + const binaryBuiltFromSource = path.resolve( + rootPath, + ".cache", + "query-engine", + "assets", + "build", + "Release", + "lmdb.node" + ) + expect(fs.existsSync(binaryBuiltFromSource)).toEqual(false) + }) +}) diff --git a/integration-tests/lmdb-regeneration/gatsby-config.js b/integration-tests/lmdb-regeneration/gatsby-config.js new file mode 100644 index 0000000000000..9e31e5d618ad2 --- /dev/null +++ b/integration-tests/lmdb-regeneration/gatsby-config.js @@ -0,0 +1,9 @@ +module.exports = { + siteMetadata: { + siteUrl: `https://www.yourdomain.tld`, + }, + plugins: [], + flags: { + DEV_SSR: true, + }, +} diff --git a/integration-tests/lmdb-regeneration/jest.config.js b/integration-tests/lmdb-regeneration/jest.config.js new file mode 100644 index 0000000000000..4e5a78b25d7bf --- /dev/null +++ b/integration-tests/lmdb-regeneration/jest.config.js @@ -0,0 +1,3 @@ +module.exports = { + testPathIgnorePatterns: [`/node_modules/`, `__tests__/fixtures`, `.cache`], +} diff --git a/integration-tests/lmdb-regeneration/package.json b/integration-tests/lmdb-regeneration/package.json new file mode 100644 index 0000000000000..7cd2ca82f4e72 --- /dev/null +++ b/integration-tests/lmdb-regeneration/package.json @@ -0,0 +1,22 @@ +{ + "name": "lmdb-regeneration", + "private": true, + "author": "Sid Chatterjee", + "description": "A simplified bare-bones starter for Gatsby with DSG", + "version": "0.1.0", + "license": "MIT", + "scripts": { + "build": "gatsby build", + "clean": "gatsby clean", + "test": "jest --runInBand" + }, + "dependencies": { + "gatsby": "next", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "fs-extra": "^11.1.0", + "jest": "^29.3.1" + } +} diff --git a/integration-tests/lmdb-regeneration/src/images/icon.png b/integration-tests/lmdb-regeneration/src/images/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..38b2fb0e467e023806c846454e35ede8af67105e GIT binary patch literal 11189 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 R^|Id+(7vmu{#Fee^?z+!bVL9E literal 0 HcmV?d00001 diff --git a/integration-tests/lmdb-regeneration/src/pages/404.jsx b/integration-tests/lmdb-regeneration/src/pages/404.jsx new file mode 100644 index 0000000000000..d7b40627e81ae --- /dev/null +++ b/integration-tests/lmdb-regeneration/src/pages/404.jsx @@ -0,0 +1,49 @@ +import * as React from "react" +import { Link } from "gatsby" + +const pageStyles = { + color: "#232129", + padding: "96px", + fontFamily: "-apple-system, Roboto, sans-serif, serif", +} +const headingStyles = { + marginTop: 0, + marginBottom: 64, + maxWidth: 320, +} + +const paragraphStyles = { + marginBottom: 48, +} +const codeStyles = { + color: "#8A6534", + padding: 4, + backgroundColor: "#FFF4DB", + fontSize: "1.25rem", + borderRadius: 4, +} + +const NotFoundPage = () => { + return ( +
+

Page not found

+

+ Sorry 😔, we couldn’t find what you were looking for. +
+ {process.env.NODE_ENV === "development" ? ( + <> +
+ Try creating a page in src/pages/. +
+ + ) : null} +
+ Go home. +

+
+ ) +} + +export default NotFoundPage + +export const Head = () => Not found diff --git a/integration-tests/lmdb-regeneration/src/pages/test-dsg.jsx b/integration-tests/lmdb-regeneration/src/pages/test-dsg.jsx new file mode 100644 index 0000000000000..db06e1909a02a --- /dev/null +++ b/integration-tests/lmdb-regeneration/src/pages/test-dsg.jsx @@ -0,0 +1,17 @@ +import * as React from "react"; + +const DSG = () => { + return

DSG

; +}; + +export default DSG; + +export const Head = () => DSG; + +export async function config() { + return () => { + return { + defer: true, + }; + }; +} diff --git a/packages/gatsby/src/schema/graphql-engine/bundle-webpack.ts b/packages/gatsby/src/schema/graphql-engine/bundle-webpack.ts index 8b5d99f4e41c2..4b87d2e5115a9 100644 --- a/packages/gatsby/src/schema/graphql-engine/bundle-webpack.ts +++ b/packages/gatsby/src/schema/graphql-engine/bundle-webpack.ts @@ -2,8 +2,10 @@ import * as path from "path" import * as fs from "fs-extra" +import execa, { Options as ExecaOptions } from "execa" import webpack, { Module, NormalModule, Compilation } from "webpack" import ConcatenatedModule from "webpack/lib/optimize/ConcatenatedModule" +import { dependencies } from "gatsby/package.json" import { printQueryEnginePlugins } from "./print-plugins" import mod from "module" import { WebpackLoggingPlugin } from "../../utils/webpack/plugins/webpack-logging" @@ -12,6 +14,7 @@ import { schemaCustomizationAPIs } from "./print-plugins" import type { GatsbyNodeAPI } from "../../redux/types" import * as nodeApis from "../../utils/api-node-docs" import { store } from "../../redux" +import { PackageJson } from "../../.." type Reporter = typeof reporter @@ -35,6 +38,92 @@ function getApisToRemoveForQueryEngine(): Array { return apisToRemove } +const getInternalPackagesCacheDir = (): string => + path.join(process.cwd(), `.cache/internal-packages`) + +// Create a directory and JS module where we install internally used packages +const createInternalPackagesCacheDir = async (): Promise => { + const cacheDir = getInternalPackagesCacheDir() + await fs.ensureDir(cacheDir) + await fs.emptyDir(cacheDir) + + const packageJsonPath = path.join(cacheDir, `package.json`) + + await fs.outputJson(packageJsonPath, { + name: `gatsby-internal-packages`, + description: `This directory contains internal packages installed by Gatsby used to comply with the current platform requirements`, + version: `1.0.0`, + private: true, + author: `Gatsby`, + license: `MIT`, + }) +} + +// lmdb module with prebuilt binaries for our platform +const lmdbPackage = `@lmdb/lmdb-${process.platform}-${process.arch}` + +// Detect if the prebuilt binaries for lmdb have been installed. These are installed under @lmdb and are tied to each platform/arch. We've seen instances where regular installations lack these modules because of a broken lockfile or skipping optional dependencies installs +function installPrebuiltLmdb(): boolean { + // Read lmdb's package.json, go through its optional depedencies and validate if there's a prebuilt lmdb module with a compatible binary to our platform and arch + let packageJson: PackageJson + try { + const modulePath = path + .dirname(require.resolve(`lmdb`)) + .replace(`/dist`, ``) + const packageJsonPath = path.join(modulePath, `package.json`) + packageJson = JSON.parse(fs.readFileSync(packageJsonPath, `utf-8`)) + } catch (e) { + // If we fail to read lmdb's package.json there's bigger problems here so just skip installation + return false + } + // If there's no lmdb prebuilt package for our arch/platform listed as optional dep no point in trying to install it + const { optionalDependencies } = packageJson + if (!optionalDependencies) return false + if (!Object.keys(optionalDependencies).find(p => p === lmdbPackage)) + return false + try { + const lmdbRequire = mod.createRequire(require.resolve(`lmdb`)) + lmdbRequire.resolve(lmdbPackage) + return false + } catch (e) { + return true + } +} + +// Install lmdb's native system module under our internal cache if we detect the current installation +// isn't using the pre-build binaries +async function installIfMissingLmdb(): Promise { + if (!installPrebuiltLmdb()) return undefined + + await createInternalPackagesCacheDir() + + const cacheDir = getInternalPackagesCacheDir() + const options: ExecaOptions = { + stderr: `inherit`, + cwd: cacheDir, + } + + const npmAdditionalCliArgs = [ + `--no-progress`, + `--no-audit`, + `--no-fund`, + `--loglevel`, + `error`, + `--color`, + `always`, + `--legacy-peer-deps`, + `--save-exact`, + ] + + await execa( + `npm`, + [`install`, ...npmAdditionalCliArgs, `${lmdbPackage}@${dependencies.lmdb}`], + options + ) + + return path.join(cacheDir, `node_modules`, lmdbPackage) +} + export async function createGraphqlEngineBundle( rootDir: string, reporter: Reporter, @@ -57,6 +146,19 @@ export async function createGraphqlEngineBundle( require.resolve(`gatsby-plugin-typescript`) ) + // Alternative lmdb path we've created to self heal from a "broken" lmdb installation + const alternativeLmdbPath = await installIfMissingLmdb() + + // We force a specific lmdb binary module if we detected a broken lmdb installation or if we detect the presence of an adapter + let forcedLmdbBinaryModule: string | undefined = undefined + if (store.getState().adapter.instance) { + forcedLmdbBinaryModule = `${lmdbPackage}/node.abi83.glibc.node` + } + // We always force the binary if we've installed an alternative path + if (alternativeLmdbPath) { + forcedLmdbBinaryModule = `${alternativeLmdbPath}/node.abi83.glibc.node` + } + const compiler = webpack({ name: `Query Engine`, // mode: `production`, @@ -121,9 +223,7 @@ export async function createGraphqlEngineBundle( { loader: require.resolve(`./lmdb-bundling-patch`), options: { - forcedBinaryModule: store.getState().adapter.instance - ? `@lmdb/lmdb-${process.platform}-${process.arch}/node.abi83.glibc.node` - : undefined, + forcedBinaryModule: forcedLmdbBinaryModule, }, }, ],