Skip to content

Commit 1a56c34

Browse files
authored
fix(gatsby-adapter-netlify): support monorepos (#39005)
* test: run e2e adapters in monorepo setup * fix(gatsby-adapter-netlify): ensure we set includedFilesBasePath so monorepo cases will bundle all required files correctly * fix(gatsby): don't rely on process.cwd() in lambda for ssr/dsg, instead infer root of 'gatsby' through relative path from entry module and set process.cwd() based on that so rest of utils relying on process.cwd() continue to work in monorepo scenarios * chore: minor cleanup * chore: bump caniuse-lite
1 parent 4ef1d47 commit 1a56c34

File tree

9 files changed

+88
-22
lines changed

9 files changed

+88
-22
lines changed

.circleci/config.yml

+19-1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,9 @@ commands:
134134
slices:
135135
type: boolean
136136
default: true # allow disabling it later when setting up partial hydration tests
137+
pre_gatsby_dev_command:
138+
type: string
139+
default: ""
137140
steps:
138141
- checkout
139142
# In case of failure, add these steps again. Cache probably got deleted
@@ -164,7 +167,7 @@ commands:
164167
command: yarn global add gatsby-dev-cli@next --ignore-engines
165168
- run:
166169
name: Run tests (using defaults)
167-
command: ./scripts/e2e-test.sh "<< parameters.test_path >>" "<< parameters.test_command >>"
170+
command: ./scripts/e2e-test.sh "<< parameters.test_path >>" "<< parameters.test_command >>" "<< parameters.pre_gatsby_dev_command >>"
168171

169172
version: 2.1
170173

@@ -507,6 +510,19 @@ jobs:
507510
- store_test_results:
508511
path: e2e-tests/adapters/cypress/results
509512

513+
e2e_tests_adapters_monorepo:
514+
<<: *e2e-executor
515+
docker:
516+
- image: cypress/browsers:node-18.16.1-chrome-114.0.5735.133-1-ff-114.0.2-edge-114.0.1823.51-1
517+
steps:
518+
- run: echo 'export CYPRESS_RECORD_KEY="${CY_CLOUD_ADAPTERS}"' >> "$BASH_ENV"
519+
- e2e-test:
520+
test_path: e2e-tests/adapters
521+
test_command: cd workspace; gatsby-dev --force-install --scan-once; cd ..; yarn test
522+
pre_gatsby_dev_command: ./make-monorepo.sh
523+
- store_test_results:
524+
path: e2e-tests/adapters/cypress/results
525+
510526
starters_validate:
511527
executor: node
512528
steps:
@@ -708,6 +724,8 @@ workflows:
708724
<<: *e2e-test-workflow
709725
- e2e_tests_adapters:
710726
<<: *e2e-test-workflow
727+
- e2e_tests_adapters_monorepo:
728+
<<: *e2e-test-workflow
711729
- e2e_tests_development_runtime_with_react_18:
712730
<<: *e2e-test-workflow
713731
- e2e_tests_production_runtime_with_react_18:

e2e-tests/adapters/make-monorepo.sh

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#!/bin/bash
2+
3+
# this script will make checked out files move around and make git working directory dirty
4+
# this is primarly for setting up monorepo structure for e2e tests that run in CI to avoid
5+
# having to maintain additional fixture as we want to test all the same things as in single repo
6+
# case
7+
8+
# move all items in the current directory to a new directory called workspace
9+
rm -rf workspace
10+
items=(*)
11+
mkdir workspace
12+
mv ${items[*]} workspace
13+
14+
# create root package.json and mark workspace directory as a npm/yarn workspace
15+
echo '{ "workspaces": ["workspace"], "scripts": { "test": "EXTRA_NTL_CLI_ARGS=\"--filter=workspace\" E2E_MONOREPO=\"true\" npm run test -w workspace" }, "private": true }' > package.json
16+
17+
# update netlify.toml build command and publish dir
18+
sed -i.bak -e 's/npm run build/npm run build -w workspace/g' -e 's/public/workspace\/public/g' workspace/netlify.toml
19+
20+
# update workspace's package.json to have correct path to helper script after moving site fixture into subdirectory
21+
sed -i.bak -e 's/..\/..\/scripts\/cypress-run-with-conditional-record-flag.js/..\/..\/..\/scripts\/cypress-run-with-conditional-record-flag.js/g' workspace/package.json
22+
23+
git init
24+

e2e-tests/adapters/netlify.toml

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
[build]
2-
command = "npm run build"
3-
publish = "public/"
2+
command = "npm run build"
3+
publish = "public/"
4+
base = ""
45

56
[build.environment]
6-
NETLIFY_IMAGE_CDN = "true"
7+
NETLIFY_IMAGE_CDN = "true"
78

89
[images]
9-
remote_images = [
10-
"https://images.unsplash.com/.*",
11-
"https://www.gatsbyjs.com/.*",
12-
]
10+
remote_images = [
11+
"https://images.unsplash.com/.*",
12+
"https://www.gatsbyjs.com/.*",
13+
]

e2e-tests/adapters/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
"cy:open": "cypress open --browser chrome --e2e",
1414
"develop:debug": "start-server-and-test develop http://localhost:8000 'npm run cy:open -- --config baseUrl=http://localhost:8000'",
1515
"ssat:debug": "start-server-and-test serve http://localhost:9000 cy:open",
16-
"test:template": "cross-env-shell CYPRESS_GROUP_NAME=\"adapter:$ADAPTER / trailingSlash:${TRAILING_SLASH:-always} / pathPrefix:${PATH_PREFIX:--}\" TRAILING_SLASH=$TRAILING_SLASH PATH_PREFIX=$PATH_PREFIX node ../../scripts/cypress-run-with-conditional-record-flag.js --browser chrome --e2e --config-file \"cypress/configs/$ADAPTER.ts\" --env TRAILING_SLASH=$TRAILING_SLASH,PATH_PREFIX=$PATH_PREFIX",
17-
"test:template:debug": "cross-env-shell CYPRESS_GROUP_NAME=\"adapter:$ADAPTER / trailingSlash:${TRAILING_SLASH:-always} / pathPrefix:${PATH_PREFIX:--} / excludeDatastoreFromBundle:${GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE:-false}\" TRAILING_SLASH=$TRAILING_SLASH PATH_PREFIX=$PATH_PREFIX npm run cy:open -- --config-file \"cypress/configs/$ADAPTER.ts\" --env TRAILING_SLASH=$TRAILING_SLASH,PATH_PREFIX=$PATH_PREFIX",
16+
"test:template": "cross-env-shell CYPRESS_GROUP_NAME=\"adapter:$ADAPTER / trailingSlash:${TRAILING_SLASH:-always} / pathPrefix:${PATH_PREFIX:--} / excludeDatastoreFromBundle:${GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE:-false} / monorepo:${E2E_MONOREPO:-false}\" TRAILING_SLASH=$TRAILING_SLASH PATH_PREFIX=$PATH_PREFIX node ../../scripts/cypress-run-with-conditional-record-flag.js --browser chrome --e2e --config-file \"cypress/configs/$ADAPTER.ts\" --env TRAILING_SLASH=$TRAILING_SLASH,PATH_PREFIX=$PATH_PREFIX",
17+
"test:template:debug": "cross-env-shell CYPRESS_GROUP_NAME=\"adapter:$ADAPTER / trailingSlash:${TRAILING_SLASH:-always} / pathPrefix:${PATH_PREFIX:--} / excludeDatastoreFromBundle:${GATSBY_EXCLUDE_DATASTORE_FROM_BUNDLE:-false} / monorepo:${E2E_MONOREPO:-false}\" TRAILING_SLASH=$TRAILING_SLASH PATH_PREFIX=$PATH_PREFIX npm run cy:open -- --config-file \"cypress/configs/$ADAPTER.ts\" --env TRAILING_SLASH=$TRAILING_SLASH,PATH_PREFIX=$PATH_PREFIX",
1818
"test:debug": "npm-run-all -s build:debug ssat:debug",
1919
"test:netlify": "cross-env TRAILING_SLASH=always node scripts/deploy-and-run/netlify.mjs test:template",
2020
"test:smoke": "node smoke-test.mjs",
@@ -38,7 +38,7 @@
3838
"dotenv": "^8.6.0",
3939
"execa": "^6.1.0",
4040
"gatsby-cypress": "^3.13.0",
41-
"netlify-cli": "^17.9.0",
41+
"netlify-cli": "^17.25.0",
4242
"npm-run-all": "^4.1.5",
4343
"start-server-and-test": "^2.0.3",
4444
"typescript": "^5.3.3"

e2e-tests/adapters/scripts/deploy-and-run/netlify.mjs

+12-3
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,16 @@ const npmScriptToRun = process.argv[2] || "test:netlify"
1919
await execa(`npm`, [`run`, `clean`], { stdio: `inherit` })
2020

2121
const deployResults = await execa(
22-
"ntl",
23-
["deploy", "--build", "--json", "--cwd=.", "--message", deployTitle],
22+
"npx",
23+
[
24+
"ntl",
25+
"deploy",
26+
"--build",
27+
"--json",
28+
"--message",
29+
deployTitle,
30+
process.env.EXTRA_NTL_CLI_ARGS ?? "--cwd=.",
31+
],
2432
{
2533
reject: false,
2634
}
@@ -49,7 +57,8 @@ try {
4957
} finally {
5058
if (!process.env.GATSBY_TEST_SKIP_CLEANUP) {
5159
console.log(`Deleting project with deploy_id ${deployInfo.deploy_id}`)
52-
const deleteResponse = await execa("ntl", [
60+
const deleteResponse = await execa("npx", [
61+
"ntl",
5362
"api",
5463
"deleteDeploy",
5564
"--data",

packages/gatsby-adapter-netlify/src/lambda-handler.ts

+1
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export async function prepareFunction(
6161
includedFiles: fun.requiredFiles.map(file =>
6262
slash(file).replace(/\[/g, `*`).replace(/]/g, `*`)
6363
),
64+
includedFilesBasePath: process.cwd(),
6465
externalNodeModules: [`msgpackr-extract`],
6566
},
6667
version: 1,

packages/gatsby/src/utils/page-ssr-module/lambda.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,22 @@ const cdnDatastorePath = `%CDN_DATASTORE_PATH%`
1717
const cdnDatastoreOrigin = `%CDN_DATASTORE_ORIGIN%`
1818
const PATH_PREFIX = `%PATH_PREFIX%`
1919

20+
// this file should be in `.cache/page-ssr-module/lambda.js`
21+
// so getting `.cache` location should be one directory above
22+
// directory of this file
23+
const cacheDir = path.join(__dirname, `..`)
24+
25+
// gatsby relies on process.cwd() a lot, so this ensures that CWD is set correctly
26+
// in relation to bundled files for lambda. In some scenarios those files are not in
27+
// expected relative locations to CWD, so here we are forcing setting CWD so the
28+
// relative paths are correct
29+
process.chdir(path.join(cacheDir, `..`))
30+
2031
function setupFsWrapper(): string {
2132
// setup global._fsWrapper
2233
try {
2334
fs.accessSync(__filename, fs.constants.W_OK)
24-
// TODO: this seems funky - not sure if this is correct way to handle this, so just marking TODO to revisit this
25-
return path.join(__dirname, `..`, `data`, `datastore`)
35+
return path.join(cacheDir, `data`, `datastore`)
2636
} catch (e) {
2737
// we are in a read-only filesystem, so we need to use a temp dir
2838

@@ -31,9 +41,6 @@ function setupFsWrapper(): string {
3141

3242
global.__GATSBY.root = TEMP_DIR
3343

34-
// TODO: don't hardcode this
35-
const cacheDir = `${process.cwd()}/.cache`
36-
3744
// we need to rewrite fs
3845
const rewrites = [
3946
[path.join(cacheDir, `caches`), path.join(TEMP_CACHE_DIR, `caches`)],

scripts/e2e-test.sh

+6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ set -e # bail on errors
33

44
SRC_PATH=$1
55
CUSTOM_COMMAND="${2:-yarn test}"
6+
PRE_GATSBY_DEV_COMMAND="${3:-}"
67
eval GATSBY_PATH=${CIRCLE_WORKING_DIRECTORY:-../..}
78
TMP_LOCATION=$(mktemp -d);
89

@@ -22,6 +23,11 @@ cp -Rv $GATSBY_PATH/scripts/. $TMP_LOCATION/scripts/
2223
# setting up child integration test link to gatsby packages
2324
cd "$TMP_TEST_LOCATION"
2425

26+
if [[ $PRE_GATSBY_DEV_COMMAND != "" ]]; then
27+
echo "Running pre-gatsby-dev command: $PRE_GATSBY_DEV_COMMAND"
28+
sh -c "$PRE_GATSBY_DEV_COMMAND"
29+
fi
30+
2531
gatsby-dev --set-path-to-repo "$GATSBY_PATH"
2632
gatsby-dev --force-install --scan-once # Do not copy files, only install through npm, like our users would
2733
if test -f "./node_modules/.bin/gatsby"; then

yarn.lock

+3-3
Original file line numberDiff line numberDiff line change
@@ -7562,9 +7562,9 @@ caniuse-api@^3.0.0:
75627562
lodash.uniq "^4.5.0"
75637563

75647564
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001538, caniuse-lite@^1.0.30001565:
7565-
version "1.0.30001572"
7566-
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001572.tgz#1ccf7dc92d2ee2f92ed3a54e11b7b4a3041acfa0"
7567-
integrity sha512-1Pbh5FLmn5y4+QhNyJE9j3/7dK44dGB83/ZMjv/qJk86TvDbjk0LosiZo0i0WB0Vx607qMX9jYrn1VLHCkN4rw==
7565+
version "1.0.30001641"
7566+
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001641.tgz"
7567+
integrity sha512-Phv5thgl67bHYo1TtMY/MurjkHhV4EDaCosezRXgZ8jzA/Ub+wjxAvbGvjoFENStinwi5kCyOYV3mi5tOGykwA==
75687568

75697569
capital-case@^1.0.4:
75707570
version "1.0.4"

0 commit comments

Comments
 (0)