Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ci: don't install fixture's deps if next version requierment is not satisfied #3103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
7d3d86f
ci: don't install fixture's deps if next version requierment is not s...
pieh Sep 4, 2025
549a40f
tmp: focus on integration tests
pieh Sep 4, 2025
6160b03
ci: use node@20 for next@canary tests
pieh Sep 4, 2025
4412893
Merge remote-tracking branch 'origin/main' into ci/dont-install-fixtu...
pieh Sep 5, 2025
53fd219
list next version when creating isolated integration fixture
pieh Sep 5, 2025
1c6e181
list next version when preparing fixtures
pieh Sep 5, 2025
d76d65a
remove some debug log
pieh Sep 5, 2025
ddff423
fix addprefix usage
pieh Sep 5, 2025
09e7ee7
no reject on npm list
pieh Sep 5, 2025
1c87edf
use pnpm list for pnpm fixtures
pieh Sep 5, 2025
4d89c0d
don't skip updating package.json for non-latest
pieh Sep 5, 2025
202a364
more fixes
pieh Sep 5, 2025
89442a6
set DEBUG=true for tests
pieh Sep 5, 2025
34073ac
check all the tests
pieh Sep 5, 2025
77d0ce3
fix vercel e2e?
pieh Sep 5, 2025
aa91ca0
no longer debug our own tests
pieh Sep 5, 2025
c5a9f6a
Merge branch 'main' into ci/dont-install-fixture-deps-if-next-version...
pieh Sep 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions .github/workflows/run-tests.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,23 @@ jobs:

steps:
- uses: actions/checkout@v5
- name: Decide Node Version
id: decide-node-version
shell: bash
run: |
NODE_VERSION=18.x
if [ "${{ matrix.version}}" = "canary" ]; then
# this is not ideal, because we set node@20 just when explicitly using canary tag as target
# but next@canary are still on 15 major, so we can't yet use major version of resolved next version
# as condition
NODE_VERSION=20.x
fi
echo "version=$NODE_VERSION" >> $GITHUB_OUTPUT
echo "Node version for 'next@${{ matrix.version }}' is '$NODE_VERSION'"
- name: 'Install Node'
uses: actions/setup-node@v4
with:
node-version: '20.x'
node-version: ${{ steps.decide-node-version.outputs.version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- uses: oven-sh/setup-bun@v2
Expand Down Expand Up @@ -118,7 +131,7 @@ jobs:
fail-fast: false
matrix:
shard: [1, 2, 3, 4, 5, 6, 7, 8]
os: [ubuntu-latest, windows-2025]
os: [ubuntu-latest]
version: ${{ fromJson(needs.setup.outputs.matrix) }}
exclude:
- os: windows-2025
Expand All @@ -128,10 +141,23 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v5
- name: Decide Node Version
id: decide-node-version
shell: bash
run: |
NODE_VERSION=18.x
if [ "${{ matrix.version}}" = "canary" ]; then
# this is not ideal, because we set node@20 just when explicitly using canary tag as target
# but next@canary are still on 15 major, so we can't yet use major version of resolved next version
# as condition
NODE_VERSION=20.x
fi
echo "version=$NODE_VERSION" >> $GITHUB_OUTPUT
echo "Node version for 'next@${{ matrix.version }}' is '$NODE_VERSION'"
- name: 'Install Node'
uses: actions/setup-node@v4
with:
node-version: '20.x'
node-version: ${{ steps.decide-node-version.outputs.version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: Prefer npm global on windows
Expand Down Expand Up @@ -205,10 +231,23 @@ jobs:
version: ${{ fromJson(needs.setup.outputs.matrix) }}
steps:
- uses: actions/checkout@v5
- name: Decide Node Version
id: decide-node-version
shell: bash
run: |
NODE_VERSION=18.x
if [ "${{ matrix.version}}" = "canary" ]; then
# this is not ideal, because we set node@20 just when explicitly using canary tag as target
# but next@canary are still on 15 major, so we can't yet use major version of resolved next version
# as condition
NODE_VERSION=20.x
fi
echo "version=$NODE_VERSION" >> $GITHUB_OUTPUT
echo "Node version for 'next@${{ matrix.version }}' is '$NODE_VERSION'"
- name: 'Install Node'
uses: actions/setup-node@v4
with:
node-version: '20.x'
Copy link
Contributor

@mrstork mrstork Sep 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we want a full revert of the last change, but I also updated node-version in a few other files. We likely don't need the same logic everywhere, but we might want to go back to 18 for some of them

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The other workflows are (that I didn't touch and were updated in https://github.com/opennextjs/opennextjs-netlify/pull/3101/files to use node 20):

  • deno unit tests (I think we use node/npm just to install deps, but otherwise use deno)
  • size check
  • lint

I don't think it really matter which node version we use there, so might as well keep them on node 20

mrstork reacted with thumbs up emoji
node-version: ${{ steps.decide-node-version.outputs.version }}
cache: 'npm'
cache-dependency-path: '**/package-lock.json'
- name: setup pnpm/yarn
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/test-e2e.yml
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ concurrency:
cancel-in-progress: true

env:
NODE_VERSION: 20.9.0
PNPM_VERSION: 8.9.0
NEXT_REPO: vercel/next.js
NEXT_TEST_MODE: deploy
Expand Down Expand Up @@ -111,10 +110,24 @@ jobs:
with:
path: ${{ env.runtime-path }}

- name: Decide Node Version
id: decide-node-version
shell: bash
run: |
NODE_VERSION=18.x
if [ "${{ matrix.version_spec.selector }}" = "canary" ]; then
# this is not ideal, because we set node@20 just when explicitly using canary tag as target
# but next@canary are still on 15 major, so we can't yet use major version of resolved next version
# as condition
NODE_VERSION=20.x
fi
echo "version=$NODE_VERSION" >> $GITHUB_OUTPUT
echo "Node version for 'next@${{ matrix.version_spec.selector }}' is '$NODE_VERSION'"

- name: setup node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
node-version: ${{ steps.decide-node-version.outputs.version }}

- name: setup pnpm/yarn
run: corepack enable
Expand Down
65 changes: 41 additions & 24 deletions tests/prepare.mjs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,12 @@ const promises = fixtures.map((fixture) =>
})
await Promise.all(publishDirectories.map((dir) => rm(dir, { recursive: true, force: true })))

if (NEXT_VERSION !== 'latest') {
await setNextVersionInFixture(cwd, NEXT_VERSION, {
logPrefix: `[${fixture}] `,
})
Comment on lines -63 to -66
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note - the similar check is now done inside setNextVersionInFixture to avoid doing any actual changes for latest, but still allow to figure out if NEXT_VERSION satisfies potential fixture constraints like those:

"test": {
"dependencies": {
"next": "canary"
}
}
"test": {
"dependencies": {
"next": ">=15.2.0"
}
}

Note - those are not "dependencies" - those our own definitions that control which next versions are applicable for this fixture (for example for node middleware fixtures, we only allow next versions that actually support that, etc)

const fixtureNextVersionSatisfied = await setNextVersionInFixture(cwd, NEXT_VERSION, {
logPrefix: `[${fixture}] `,
})

if (!fixtureNextVersionSatisfied) {
return
}

let cmd = ``
Expand All @@ -79,19 +81,26 @@ const promises = fixtures.map((fixture) =>
await rm(join(cwd, 'package-lock.json'), { force: true })
}

const addPrefix = new Transform({
transform(chunk, encoding, callback) {
this.push(chunk.toString().replace(/\n/gm, `\n[${fixture}] `))
callback()
},
flush(callback) {
// final transform might create non-terminated line with a prefix
// so this is just to make sure we end with a newline so further writes
// to same destination stream start on a new line for better readability
this.push('\n')
callback()
},
})
const addPrefix = () => {
let isFirstChunk = true
return new Transform({
transform(chunk, encoding, callback) {
if (isFirstChunk) {
this.push(`[${fixture}] `)
isFirstChunk = false
}
this.push(chunk.toString().replace(/\n/gm, `\n[${fixture}] `))
callback()
},
flush(callback) {
// final transform might create non-terminated line with a prefix
// so this is just to make sure we end with a newline so further writes
// to same destination stream start on a new line for better readability
this.push('\n')
callback()
},
})
}
Comment on lines +84 to +103
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note - previous setup with reusing same transform was resulting in only seeing output from 1 .pipe() - so instead for each .pipe we create clone of transform (this was noticed when I used DEBUG condition to print out npm/pnpm list next that output was silent for that)


console.log(`[${fixture}] Running \`${cmd}\`...`)
const output = execaCommand(cmd, {
Expand All @@ -100,16 +109,24 @@ const promises = fixtures.map((fixture) =>
env: { ...process.env, FORCE_COLOR: '1' },
})
if (process.env.DEBUG) {
output.stdout?.pipe(addPrefix).pipe(process.stdout)
output.stdout?.pipe(addPrefix()).pipe(process.stdout)
}
output.stderr?.pipe(addPrefix).pipe(process.stderr)
output.stderr?.pipe(addPrefix()).pipe(process.stderr)
return output.finally(async () => {
if (NEXT_VERSION !== 'latest') {
await setNextVersionInFixture(cwd, 'latest', {
logPrefix: `[${fixture}] `,
operation: 'revert',
})
if (process.env.DEBUG) {
const npmListPromise = execaCommand(
packageManager?.startsWith('pnpm') ? 'pnpm list next' : 'npm list next',
{ cwd, stdio: 'pipe', reject: false },
)
npmListPromise.stdout?.pipe(addPrefix()).pipe(process.stdout)
npmListPromise.stderr?.pipe(addPrefix()).pipe(process.stderr)
await npmListPromise
}
Comment on lines +116 to 124
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was useful in debugging, so I think I'd like to leave this here (behind DEBUG toggle to avoid it being too spammy in regular usage)


await setNextVersionInFixture(cwd, 'latest', {
logPrefix: `[${fixture}] `,
operation: 'revert',
})
if (output.exitCode !== 0) {
const errorMessage = `[${fixture}] 🚨 Failed to install dependencies or build a fixture`
console.error(errorMessage)
Expand Down
4 changes: 1 addition & 3 deletions tests/utils/create-e2e-fixture.ts
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,7 @@ export const createE2EFixture = async (fixture: string, config: E2EConfig = {})
copyFixture(fixture, isolatedFixtureRoot, config),
])

if (NEXT_VERSION !== 'latest') {
await setNextVersionInFixture(isolatedFixtureRoot, NEXT_VERSION)
}
await setNextVersionInFixture(isolatedFixtureRoot, NEXT_VERSION)
await installRuntime(packageName, isolatedFixtureRoot, config)
await verifyFixture(isolatedFixtureRoot, config)

Expand Down
23 changes: 15 additions & 8 deletions tests/utils/fixture.ts
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,27 @@ const eszipHelper = join(actualCwd, 'tools/deno/eszip.ts')

async function installDependencies(cwd: string) {
const NEXT_VERSION = process.env.NEXT_VERSION ?? 'latest'
if (NEXT_VERSION !== 'latest') {
await setNextVersionInFixture(cwd, NEXT_VERSION, { silent: true })
}
await setNextVersionInFixture(cwd, NEXT_VERSION, { silent: true })

const { packageManager } = JSON.parse(await readFile(join(cwd, 'package.json'), 'utf8'))
if (packageManager?.startsWith('pnpm')) {
return execaCommand(`pnpm install --ignore-scripts --reporter=silent`, {
await execaCommand(`pnpm install --ignore-scripts --reporter=silent`, {
cwd,
})
} else {
await execaCommand(
`npm install --ignore-scripts --no-audit --progress=false --legacy-peer-deps`,
{ cwd },
)
}

if (process.env.DEBUG) {
await execaCommand(packageManager?.startsWith('pnpm') ? `pnpm list next` : 'npm list next', {
cwd,
stdio: 'inherit',
reject: false,
})
}
return execaCommand(
`npm install --ignore-scripts --no-audit --progress=false --legacy-peer-deps`,
{ cwd },
)
}

export const getFixtureSourceDirectory = (fixture: string) =>
Expand Down
44 changes: 34 additions & 10 deletions tests/utils/next-version-helpers.mjs
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export function nextVersionRequiresReact19(version) {
* @param {'update' | 'revert'} [options.operation] This just informs log output wording, otherwise it has no effect
* @param {boolean} [options.silent] Doesn't produce any logs if truthy
* @param {boolean} [options.updateReact] Update React version to match Next version
* @returns {Promise<void>}
* @returns {Promise<boolean>} true if fixture's next version requirements are satisfied
*/
export async function setNextVersionInFixture(
cwd,
Expand All @@ -87,20 +87,14 @@ export async function setNextVersionInFixture(
// if resolved version is different from version, we add it to the log to provide additional details
const nextVersionForLogs = `next@${version}${resolvedVersion !== version ? ` (${resolvedVersion})` : ``}`

if (!silent) {
console.log(
`${logPrefix}さんかく ${operation === 'revert' ? 'Reverting' : 'Updating'} to ${nextVersionForLogs}...`,
)
}

const packageJsons = await fg.glob(['**/package.json', '!**/node_modules'], {
cwd,
absolute: true,
})

const isSemverVersion = valid(resolvedVersion)

await Promise.all(
const areNextVersionConstraintsSatisfied = await Promise.all(
packageJsons.map(async (packageJsonPath) => {
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'))
if (packageJson.dependencies?.next) {
Expand All @@ -110,17 +104,45 @@ export async function setNextVersionInFixture(
if (
operation === 'update' &&
versionConstraint &&
!satisfies(checkVersion, versionConstraint, { includePrerelease: true }) &&
!(versionConstraint === 'canary'
? isNextCanary()
: satisfies(checkVersion, versionConstraint, { includePrerelease: true })) &&
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not ideal, but as mentioned few lines above (Line 103) - we can't really use semver's satisfies when a tag (like canary) is used, so this is alternative solution for that

version !== versionConstraint
) {
if (!silent) {
console.log(
`${logPrefix}⏩ Skipping '${packageJson.name}' because it requires next@${versionConstraint}`,
)
}
return
return false
}
}
return true
}),
)

if (areNextVersionConstraintsSatisfied.some((isSatisfied) => !isSatisfied)) {
// at least one next version constraint is not satisfied so we skip this fixture
return false
}

if ((process.env.NEXT_VERSION ?? 'latest') === 'latest') {
// latest is default so we don't want to make any changes
return true
}

if (!silent) {
console.log(
`${logPrefix}さんかく ${operation === 'revert' ? 'Reverting' : 'Updating'} to ${nextVersionForLogs}...`,
)
}

await Promise.all(
packageJsons.map(async (packageJsonPath) => {
const packageJson = JSON.parse(await readFile(packageJsonPath, 'utf8'))
if (packageJson.dependencies?.next) {
packageJson.dependencies.next = version
const checkVersion = isSemverVersion ? resolvedVersion : FUTURE_NEXT_PATCH_VERSION

const { stdout } = await execaCommand(
`npm info next@${resolvedVersion} peerDependencies --json`,
Expand Down Expand Up @@ -172,4 +194,6 @@ export async function setNextVersionInFixture(
`${logPrefix}さんかく ${operation === 'revert' ? 'Reverted' : 'Updated'} to ${nextVersionForLogs}`,
)
}

return true
}
Loading

AltStyle によって変換されたページ (->オリジナル) /