-
Notifications
You must be signed in to change notification settings - Fork 91
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
Changes from 16 commits
7d3d86f
549a40f
6160b03
4412893
53fd219
1c6e181
d76d65a
ddff423
09e7ee7
1c87edf
4d89c0d
202a364
89442a6
34073ac
77d0ce3
aa91ca0
c5a9f6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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 | ||
|
@@ -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' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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):
I don't think it really matter which node version we use there, so might as well keep them on node 20 |
||
node-version: ${{ steps.decide-node-version.outputs.version }} | ||
cache: 'npm' | ||
cache-dependency-path: '**/package-lock.json' | ||
- name: setup pnpm/yarn | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Note - the similar check is now done inside opennextjs-netlify/tests/fixtures/ppr/package.json Lines 15 to 19 in 5e28132
"test": {
"dependencies": {
"next": "canary"
}
}
opennextjs-netlify/tests/fixtures/middleware-node-runtime-specific/package.json Lines 15 to 19 in 5e28132
"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 = `` | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
||
console.log(`[${fixture}] Running \`${cmd}\`...`) | ||
const output = execaCommand(cmd, { | ||
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
|
||
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) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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, | ||
|
@@ -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) { | ||
|
@@ -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 })) && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
||
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`, | ||
|
@@ -172,4 +194,6 @@ export async function setNextVersionInFixture( | |
`${logPrefix}▲さんかく ${operation === 'revert' ? 'Reverted' : 'Updated'} to ${nextVersionForLogs}`, | ||
) | ||
} | ||
|
||
return true | ||
} |