Skip to content

Commit

Permalink
RSC: Smoke test (#9194)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tobbe authored Sep 29, 2023
1 parent 27d33d3 commit 18555d0
Show file tree
Hide file tree
Showing 17 changed files with 568 additions and 6 deletions.
2 changes: 0 additions & 2 deletions .github/actions/actionsLib.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ function execWithEnv(command, { env = {}, ...rest } = {}) {
command,
undefined,
{
// @ts-expect-error TS doesn't like spreading process.env here but it's fine for our purposes.
env: {
...process.env,
...env
Expand Down Expand Up @@ -68,7 +67,6 @@ export async function createCacheKeys({ baseKeyPrefix, distKeyPrefix }) {
const baseKey = [
baseKeyPrefix,
process.env.RUNNER_OS,
// @ts-expect-error not sure how to change the lib compiler option to es2021+ here.
process.env.GITHUB_REF.replaceAll('/', '-'),
await hashFiles(path.join('__fixtures__', 'test-project'))
].join('-')
Expand Down
9 changes: 9 additions & 0 deletions .github/actions/rsc_related_changes/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name: RSC Related Changes
description: Determines if the PR makes any changes related to RSCs
outputs:
rsc-related-changes:
description: If the PR makes any RSC related changes
runs:
# `node18` isn't supported yet
using: node16
main: rsc_related_changes.mjs
9 changes: 9 additions & 0 deletions .github/actions/rsc_related_changes/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"name": "only_doc_changes",
"private": true,
"dependencies": {
"@actions/core": "1.10.0",
"@actions/exec": "1.1.1"
},
"packageManager": "[email protected]"
}
46 changes: 46 additions & 0 deletions .github/actions/rsc_related_changes/rsc_related_changes.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import core from '@actions/core'
import { exec, getExecOutput } from '@actions/exec'

async function main() {
const branch = process.env.GITHUB_BASE_REF

// If there is no branch, we're not in a pull request
if (!branch) {
core.setOutput('rsc-related-changes', false)
return
}

await exec(`git fetch origin ${branch}`)

const { stdout } = await getExecOutput(
`git diff origin/${branch} --name-only`
)

const changedFiles = stdout.toString().trim().split('\n').filter(Boolean)

for (const changedFile of changedFiles) {
console.log('changedFile', changedFile)

// As the RSC implementation changes, this list will need to be updated.
// Also, I could be much more specific here, but then I'd also have to
// update this list much more often. So this'll serve as a good enough
// starting point.
if (
changedFile.startsWith('tasks/smoke-tests/rsc/') ||
changedFile.startsWith('tasks/smoke-tests/basePlaywright.config.ts') ||
changedFile.startsWith('.github/actions/set-up-rsc-project/') ||
changedFile.startsWith('github/actions/rsc_related_changes/') ||
changedFile.startsWith('packages/internal/') ||
changedFile.startsWith('packages/project-config/') ||
changedFile.startsWith('packages/web/') ||
changedFile.startsWith('packages/vite/')
) {
core.setOutput('rsc-related-changes', true)
return
}
}

core.setOutput('rsc-related-changes', false)
}

main()
66 changes: 66 additions & 0 deletions .github/actions/rsc_related_changes/yarn.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# This file is generated by running "yarn install" inside your project.
# Manual changes might be lost - proceed with caution!

__metadata:
version: 6
cacheKey: 8c0

"@actions/core@npm:1.10.0":
version: 1.10.0
resolution: "@actions/core@npm:1.10.0"
dependencies:
"@actions/http-client": ^2.0.1
uuid: ^8.3.2
checksum: 9214d1e0cf5cf2a5d48b8f3b12488c6be9f6722ea60f2397409226e8410b5a3e12e558d9b66c93469d180399865ec20180119408a1770f026bd9ecac6965fcda
languageName: node
linkType: hard

"@actions/exec@npm:1.1.1":
version: 1.1.1
resolution: "@actions/exec@npm:1.1.1"
dependencies:
"@actions/io": ^1.0.1
checksum: 4a09f6bdbe50ce68b5cf8a7254d176230d6a74bccf6ecc3857feee209a8c950ba9adec87cc5ecceb04110182d1c17117234e45557d72fde6229b7fd3a395322a
languageName: node
linkType: hard

"@actions/http-client@npm:^2.0.1":
version: 2.0.1
resolution: "@actions/http-client@npm:2.0.1"
dependencies:
tunnel: ^0.0.6
checksum: b58987ba2f53d7988f612ede7ff834573a3360c21f8fdea9fea92f26ada0fd0efafb22aa7d83f49c18965a5b765775d5253e2edb8d9476d924c4b304ef726b67
languageName: node
linkType: hard

"@actions/io@npm:^1.0.1":
version: 1.1.2
resolution: "@actions/io@npm:1.1.2"
checksum: 61c871bbee1cf58f57917d9bb2cf6bb7ea4dc40de3f65c7fb4ec619ceff57fc98f56be9cca2d476b09e7a96e1cba0d88cd125c4f690d384b9483935186f256c1
languageName: node
linkType: hard

"only_doc_changes@workspace:.":
version: 0.0.0-use.local
resolution: "only_doc_changes@workspace:."
dependencies:
"@actions/core": 1.10.0
"@actions/exec": 1.1.1
languageName: unknown
linkType: soft

"tunnel@npm:^0.0.6":
version: 0.0.6
resolution: "tunnel@npm:0.0.6"
checksum: e27e7e896f2426c1c747325b5f54efebc1a004647d853fad892b46d64e37591ccd0b97439470795e5262b5c0748d22beb4489a04a0a448029636670bfd801b75
languageName: node
linkType: hard

"uuid@npm:^8.3.2":
version: 8.3.2
resolution: "uuid@npm:8.3.2"
bin:
uuid: dist/bin/uuid
checksum: bcbb807a917d374a49f475fae2e87fdca7da5e5530820ef53f65ba1d12131bd81a92ecf259cc7ce317cbe0f289e7d79fdfebcef9bfa3087c8c8a2fa304c9be54
languageName: node
linkType: hard
32 changes: 32 additions & 0 deletions .github/actions/set-up-rsc-project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# GitHub action to create a RW project with RSCs set up

This action creates a RW project with Streaming SSR and RSC support set up.
It's used for RSC smoke tests.

It runs `npx -y create-redwood-app@canary ...` to set the project up with the
latest canary release of Redwood. It then runs
`experimental setup-streaming-ssr` and `experimental setup-rsc` followed by
a build of the rw app. Finally it runs `project:copy` to get the latest
changes to the framework (i.e. the changes introduced by the PR triggering this
action) into the project.

## Testing/running locally

Go into the github actions folder
`cd .github/actions`

Then run the following command to execute the action
`node set-up-rsc-project/setUpRscProjectLocally.mjs`

## Design

The main logic of the action is in the `setUpRscProject.mjs` file. To be able
to run that code both on GitHub and locally it uses dependency injection. The
injection is done by `setupRscProjectLocally.mjs` for when you want to run
the action on your own machine and by `setupRscProjectGitHib.mjs` when it's
triggered by GitHub CI.

When doing further changes to the code here it's very important to keep the
DI scripts as light on logic as possible. Ideally all logic is kept to
`setUpRscProject.mjs` so that the same logic is used both locally and on
GitHub.
10 changes: 10 additions & 0 deletions .github/actions/set-up-rsc-project/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
name: Set up RSC test project
description: Sets up an RSC project for smoke-tests

runs:
using: node20
main: 'setUpRscProjectGitHub.mjs'

outputs:
test-project-path:
description: Path to the test project
11 changes: 11 additions & 0 deletions .github/actions/set-up-rsc-project/jsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"compilerOptions": {
"noEmit": true,
"esModuleInterop": true,
"target": "esnext",
"module": "esnext",
"moduleResolution": "node",
"skipLibCheck": false,
"jsx": "react-jsx"
},
}
6 changes: 6 additions & 0 deletions .github/actions/set-up-rsc-project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "set-up-rsc-project",
"version": "0.0.0",
"private": true,
"type": "module"
}
105 changes: 105 additions & 0 deletions .github/actions/set-up-rsc-project/setUpRscProject.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/* eslint-env node */
// @ts-check

import path from 'node:path'

import { REDWOOD_FRAMEWORK_PATH } from '../actionsLib.mjs'

/**
* @typedef {import('@actions/exec').ExecOptions} ExecOptions
*/

/**
* Exec a command.
* Output will be streamed to the live console.
* Returns promise with return code
*
* @callback Exec
* @param {string} commandLine command to execute (can include additional args). Must be correctly escaped.
* @param {string[]=} args arguments for tool. Escaping is handled by the lib.
* @param {ExecOptions=} options exec options. See ExecOptions
* @returns {Promise<unknown>} exit code
*/

/**
* @callback ExecInProject
* @param {string} commandLine command to execute (can include additional args). Must be correctly escaped.
* @param {Omit<ExecOptions, "cwd">=} options exec options. See ExecOptions
* @returns {Promise<unknown>} exit code
*/

/**
* @param {string} rscProjectPath
* @param {Object} core
* @param {(key: string, value: string) => void} core.setOutput
* @param {Exec} exec
* @param {ExecInProject} execInProject
* @returns {Promise<void>}
*/
export async function main(
rscProjectPath,
core,
exec,
execInProject
) {
core.setOutput('rsc-project-path', rscProjectPath)

console.log('rwPath', REDWOOD_FRAMEWORK_PATH)
console.log('rscProjectPath', rscProjectPath)

await setUpRscProject(
rscProjectPath,
exec,
execInProject,
)
}

/**
* @param {string} rscProjectPath
* @param {Exec} exec
* @param {ExecInProject} execInProject
* @returns {Promise<void>}
*/
async function setUpRscProject(
rscProjectPath,
exec,
execInProject,
) {
const rwBinPath = path.join(
REDWOOD_FRAMEWORK_PATH,
'packages/cli/dist/index.js'
)
const rwfwBinPath = path.join(
REDWOOD_FRAMEWORK_PATH,
'packages/cli/dist/rwfw.js'
)

console.log(`Creating project at ${rscProjectPath}`)
console.log()
await exec('npx', [
'-y',
'create-redwood-app@canary',
'-y',
'--no-git',
rscProjectPath,
])

console.log(`Setting up Streaming/SSR in ${rscProjectPath}`)
const cmdSetupStreamingSSR = `node ${rwBinPath} experimental setup-streaming-ssr -f`
await execInProject(cmdSetupStreamingSSR)
console.log()

console.log(`Setting up RSC in ${rscProjectPath}`)
await execInProject(`node ${rwBinPath} experimental setup-rsc`)
console.log()

console.log(`Building project in ${rscProjectPath}`)
await execInProject(`node ${rwBinPath} build -v`)
console.log()

console.log(`Building project in ${rscProjectPath}`)
await execInProject(`node ${rwfwBinPath} project:copy`, {
env: { RWFW_PATH: REDWOOD_FRAMEWORK_PATH },
})
console.log()
}
17 changes: 17 additions & 0 deletions .github/actions/set-up-rsc-project/setUpRscProjectGitHub.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-env node */
// @ts-check

import path from 'node:path'

import core from '@actions/core'
import { exec } from '@actions/exec'

import { createExecWithEnvInCwd } from '../actionsLib.mjs'

import { main } from './setUpRscProject.mjs'

const rscProjectPath = path.join(path.dirname(process.cwd()), 'rsc-project')

const execInProject = createExecWithEnvInCwd(rscProjectPath)

main(rscProjectPath, core, exec, execInProject)
Loading

0 comments on commit 18555d0

Please sign in to comment.