Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 55 additions & 0 deletions .github/read-me.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,61 @@ Most workflows use minimal permissions. The comment-triggered workflows require:
- `pull-requests: write` - To post comments and reactions
- `actions: write` - To trigger other workflows

## Manually Triggering Workflows

Many workflows support manual triggering via `workflow_dispatch`, which allows you to run them on-demand from any branch.

### Using the GitHub UI

**Important**: The "Run workflow" button only appears for workflows that exist on the **default branch (master)**. If you've added or modified a workflow in a feature branch, you won't see the button until the workflow is merged to master.

To manually trigger a workflow in the GitHub UI:

1. Go to the **Actions** tab in the repository
2. Select the workflow from the left sidebar (e.g., "JS unit tests for Renderer package")
3. Click the **"Run workflow"** dropdown button (top right)
4. Select the branch you want to run it on
5. Configure any input parameters (e.g., `force_run` to bypass change detection)
6. Click **"Run workflow"**

### Using the GitHub CLI

You can trigger workflows from the command line without waiting for them to be merged to master:

```bash
# Basic manual trigger on current branch
gh workflow run package-js-tests.yml

# Trigger on a specific branch (e.g., master)
gh workflow run package-js-tests.yml --ref master

# Trigger with force_run parameter to bypass change detection
gh workflow run package-js-tests.yml --ref master -f force_run=true

# List available workflows
gh workflow list

# View recent workflow runs
gh run list --workflow=package-js-tests.yml
```

### Workflows Supporting Manual Triggers

The following workflows can be manually triggered with `workflow_dispatch`:

- **`package-js-tests.yml`** - Accepts `force_run` parameter (boolean) to bypass change detection
- **`lint-js-and-ruby.yml`** - Accepts `force_run` parameter (boolean) to bypass change detection
- **`playwright.yml`** - Can be triggered manually (does not accept `force_run` parameter)

Other workflows may also support `workflow_dispatch`. Check individual workflow files in `.github/workflows/` for `workflow_dispatch` configuration and available input parameters.

### Why Use Manual Triggers?

- **Test workflow changes** before merging (via CLI only until merged to master)
- **Re-run CI on master** without making a new commit
- **Force full test suite** on a branch using `force_run=true`
- **Debug CI issues** by running workflows on specific commits

## Conditional Execution

Many workflows use change detection to skip unnecessary jobs:
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/pro-test-package-and-gem.yml
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,10 @@ jobs:
sudo yarn global add yalc
yarn install --frozen-lockfile --no-progress --no-emoji

- name: Setup test environment for node-renderer tests
working-directory: .
run: bash packages/react-on-rails-pro-node-renderer/scripts/setup-test-env.sh

- name: Run JS unit tests for Pro package
run: yarn workspace react-on-rails-pro-node-renderer run ci
env:
Expand Down
1 change: 1 addition & 0 deletions packages/react-on-rails-pro-node-renderer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
"./tests/helper.ts"
],
"testEnvironment": "node",
"testTimeout": 30000,
"transform": {
"^.+\\.[jt]sx?$": "babel-jest"
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#!/bin/bash
set -e

# The node-renderer tests expect webpack bundles at spec/dummy/ssr-generated/
# but they're only built in react_on_rails_pro/spec/dummy/ssr-generated/
# This script copies them to the expected location for testing.
#
# This is necessary because:
# 1. The Pro dummy app (react_on_rails_pro/spec/dummy) has webpack configured
# 2. The node-renderer tests need to reference those built bundles
# 3. Tests run in packages/react-on-rails-pro-node-renderer/tests/
# 4. Test fixtures reference bundles at spec/dummy/ssr-generated (workspace root dummy app)

echo "Setting up test environment for react-on-rails-pro-node-renderer..."

# Determine the script's directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PACKAGE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
WORKSPACE_ROOT="$(cd "$PACKAGE_DIR/../.." && pwd)"
PRO_DUMMY="$WORKSPACE_ROOT/react_on_rails_pro/spec/dummy"
ROOT_DUMMY="$WORKSPACE_ROOT/spec/dummy"

# Check if bundles exist in Pro dummy
if [ ! -f "$PRO_DUMMY/ssr-generated/server-bundle.js" ] || [ ! -f "$PRO_DUMMY/ssr-generated/rsc-bundle.js" ]; then
echo "ERROR: Test bundles not found in $PRO_DUMMY/ssr-generated/"
echo "Please run 'yarn build:test' in react_on_rails_pro/spec/dummy first."
exit 1
fi

# Create directories for bundle copies
echo "Creating bundle directories..."
mkdir -p "$ROOT_DUMMY/ssr-generated"
mkdir -p "$ROOT_DUMMY/public/webpack/test"

# Copy bundles to expected locations
echo "Copying bundles to test locations..."
cp "$PRO_DUMMY/ssr-generated"/*.js "$ROOT_DUMMY/ssr-generated/"

# Copy or create manifest files
echo "Copying manifest files..."
if [ -f "$PRO_DUMMY/public/webpack/test/react-client-manifest.json" ]; then
cp "$PRO_DUMMY/public/webpack/test/react-client-manifest.json" "$ROOT_DUMMY/public/webpack/test/"
else
echo "{}" > "$ROOT_DUMMY/public/webpack/test/react-client-manifest.json"
fi

if [ -f "$PRO_DUMMY/ssr-generated/react-server-client-manifest.json" ]; then
cp "$PRO_DUMMY/ssr-generated/react-server-client-manifest.json" "$ROOT_DUMMY/ssr-generated/"
else
echo "{}" > "$ROOT_DUMMY/ssr-generated/react-server-client-manifest.json"
fi

echo "✓ Test environment setup complete!"
echo ""
echo "Bundles copied from:"
echo " $PRO_DUMMY/ssr-generated/"
echo "To:"
echo " $ROOT_DUMMY/ssr-generated/"
echo ""
echo "You can now run tests with:"
echo " cd packages/react-on-rails-pro-node-renderer"
echo " yarn test tests/htmlStreaming.test.js"
37 changes: 26 additions & 11 deletions packages/react-on-rails-pro-node-renderer/tests/vm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,8 @@ describe('buildVM and runInVM', () => {
});

test('FriendsAndGuests bundle for commit 1a7fe417 requires supportModules false', async () => {
expect.assertions(10);
// Testing 5 components with 3 assertions each (HTML structure, no rendering errors, length check)
expect.assertions(15);

const project = 'friendsandguests';
const commit = '1a7fe417';
Expand All @@ -215,7 +216,8 @@ describe('buildVM and runInVM', () => {
);
const welcomePageRenderingResult = await runInVM(welcomePageComponentRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(welcomePageRenderingResult as string).toContain('<');
expect(welcomePageRenderingResult as string).toContain('<div');
expect(welcomePageRenderingResult as string).not.toContain('hasErrors');
expect((welcomePageRenderingResult as string).length).toBeGreaterThan(100);

// LayoutNavbar component:
Expand All @@ -229,7 +231,8 @@ describe('buildVM and runInVM', () => {
serverBundlePath,
);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(layoutNavbarRenderingResult as string).toContain('<');
expect(layoutNavbarRenderingResult as string).toContain('<div');
expect(layoutNavbarRenderingResult as string).not.toContain('hasErrors');
expect((layoutNavbarRenderingResult as string).length).toBeGreaterThan(100);

// ListingIndex component:
Expand All @@ -243,7 +246,8 @@ describe('buildVM and runInVM', () => {
serverBundlePath,
);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(listingIndexRenderingResult as string).toContain('<');
expect(listingIndexRenderingResult as string).toContain('<div');
expect(listingIndexRenderingResult as string).not.toContain('hasErrors');
expect((listingIndexRenderingResult as string).length).toBeGreaterThan(100);

// ListingShow component:
Expand All @@ -254,7 +258,8 @@ describe('buildVM and runInVM', () => {
);
const listingShowRenderingResult = await runInVM(listingShowComponentRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(listingShowRenderingResult as string).toContain('<');
expect(listingShowRenderingResult as string).toContain('<div');
expect(listingShowRenderingResult as string).not.toContain('hasErrors');
expect((listingShowRenderingResult as string).length).toBeGreaterThan(100);

// UserShow component:
Expand All @@ -265,12 +270,14 @@ describe('buildVM and runInVM', () => {
);
const userShowRenderingResult = await runInVM(userShowComponentRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(userShowRenderingResult as string).toContain('<');
expect(userShowRenderingResult as string).toContain('<div');
expect(userShowRenderingResult as string).not.toContain('hasErrors');
expect((userShowRenderingResult as string).length).toBeGreaterThan(100);
});

test('ReactWebpackRailsTutorial bundle for commit ec974491', async () => {
expect.assertions(6);
// Testing 3 components with 3 assertions each (HTML structure, no rendering errors, length check)
expect.assertions(9);

const project = 'react-webpack-rails-tutorial';
const commit = 'ec974491';
Expand All @@ -292,7 +299,8 @@ describe('buildVM and runInVM', () => {
serverBundlePath,
);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(navigationBarRenderingResult as string).toContain('<');
expect(navigationBarRenderingResult as string).toContain('<div');
expect(navigationBarRenderingResult as string).not.toContain('hasErrors');
expect((navigationBarRenderingResult as string).length).toBeGreaterThan(100);

// RouterApp component:
Expand All @@ -303,19 +311,22 @@ describe('buildVM and runInVM', () => {
);
const routerAppRenderingResult = await runInVM(routerAppComponentRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(routerAppRenderingResult as string).toContain('<');
expect(routerAppRenderingResult as string).toContain('<div');
expect(routerAppRenderingResult as string).not.toContain('hasErrors');
expect((routerAppRenderingResult as string).length).toBeGreaterThan(100);

// App component:
const appComponentRenderingRequest = readRenderingRequest(project, commit, 'appRenderingRequest.js');
const appRenderingResult = await runInVM(appComponentRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, verify component rendered successfully
expect(appRenderingResult as string).toContain('<');
expect(appRenderingResult as string).toContain('<div');
expect(appRenderingResult as string).not.toContain('hasErrors');
expect((appRenderingResult as string).length).toBeGreaterThan(100);
});

test('BionicWorkshop bundle for commit fa6ccf6b', async () => {
expect.assertions(8);
// Testing 4 components with 3 assertions each (HTML structure, no rendering errors, length check)
expect.assertions(12);

const project = 'bionicworkshop';
const commit = 'fa6ccf6b';
Expand All @@ -339,6 +350,7 @@ describe('buildVM and runInVM', () => {

// React 19 removed data-react-checksum, check that component rendered successfully
expect(signInPageWithFlashRenderingResult as string).toContain('<div');
expect(signInPageWithFlashRenderingResult as string).not.toContain('hasErrors');
expect((signInPageWithFlashRenderingResult as string).length).toBeGreaterThan(100);

// Landing page component:
Expand All @@ -350,13 +362,15 @@ describe('buildVM and runInVM', () => {
const landingPageRenderingResult = await runInVM(landingPageRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, check that component rendered successfully
expect(landingPageRenderingResult as string).toContain('<div');
expect(landingPageRenderingResult as string).not.toContain('hasErrors');
expect((landingPageRenderingResult as string).length).toBeGreaterThan(100);

// Post page component:
const postPageRenderingRequest = readRenderingRequest(project, commit, 'postPageRenderingRequest.js');
const postPageRenderingResult = await runInVM(postPageRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, check that component rendered successfully
expect(postPageRenderingResult as string).toContain('<div');
expect(postPageRenderingResult as string).not.toContain('hasErrors');
expect((postPageRenderingResult as string).length).toBeGreaterThan(100);

// Authors page component:
Expand All @@ -368,6 +382,7 @@ describe('buildVM and runInVM', () => {
const authorsPageRenderingResult = await runInVM(authorsPageRenderingRequest, serverBundlePath);
// React 19 removed data-react-checksum, check that component rendered successfully
expect(authorsPageRenderingResult as string).toContain('<div');
expect(authorsPageRenderingResult as string).not.toContain('hasErrors');
expect((authorsPageRenderingResult as string).length).toBeGreaterThan(100);
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import formAutoContent from 'form-auto-content';
import fs from 'fs';
import querystring from 'querystring';
import { createReadStream } from 'fs-extra';
// eslint-disable-next-line import/no-relative-packages
// Import this package's version and protocolVersion, not the workspace root's
import packageJson from '../package.json';
import worker, { disableHttp2 } from '../src/worker';
import {
Expand Down
3 changes: 3 additions & 0 deletions react_on_rails_pro/spec/dummy/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ config/react_on_rails_pro_license.key
/blob-report/
/playwright/.cache/
/playwright/.auth/

# Generated files
client/app/generated/
Loading