Skip to content
Merged
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
23 changes: 20 additions & 3 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ on:
- '**.md'
- 'docs/**'
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

jobs:
detect-changes:
Expand All @@ -32,6 +38,17 @@ jobs:
- name: Detect relevant changes
id: detect
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
echo "run_lint=true" >> "$GITHUB_OUTPUT"
echo "run_js_tests=true" >> "$GITHUB_OUTPUT"
echo "run_ruby_tests=true" >> "$GITHUB_OUTPUT"
echo "run_dummy_tests=true" >> "$GITHUB_OUTPUT"
echo "run_generators=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
Expand All @@ -52,9 +69,9 @@ jobs:
- ruby-version: '3.2'
dependency-level: 'minimum'
exclude:
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && '3.2' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && 'minimum' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && '3.2' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && 'minimum' || '' }}
env:
SKIP_YARN_COREPACK_CHECK: 0
BUNDLE_FROZEN: ${{ matrix.dependency-level == 'minimum' && 'false' || 'true' }}
Expand Down
33 changes: 25 additions & 8 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ on:
- '**.md'
- 'docs/**'
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

jobs:
detect-changes:
Expand All @@ -32,6 +38,17 @@ jobs:
- name: Detect relevant changes
id: detect
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
echo "run_lint=true" >> "$GITHUB_OUTPUT"
echo "run_js_tests=true" >> "$GITHUB_OUTPUT"
echo "run_ruby_tests=true" >> "$GITHUB_OUTPUT"
echo "run_dummy_tests=true" >> "$GITHUB_OUTPUT"
echo "run_generators=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
Expand All @@ -53,10 +70,10 @@ jobs:
node-version: '20'
dependency-level: 'minimum'
exclude:
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && 'minimum' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && 'minimum' || '' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -143,10 +160,10 @@ jobs:
node-version: '20'
dependency-level: 'minimum'
exclude:
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && 'minimum' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && 'minimum' || '' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/pro-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
- 'master'
pull_request:
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

defaults:
run:
Expand All @@ -27,6 +33,14 @@ jobs:
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/pro-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
- 'master'
pull_request:
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

defaults:
run:
Expand All @@ -27,6 +33,14 @@ jobs:
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/pro-package-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ on:
- 'master'
pull_request:
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

defaults:
run:
Expand All @@ -27,6 +33,14 @@ jobs:
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi
BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
Expand Down
115 changes: 84 additions & 31 deletions .github/workflows/run-skipped-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,39 +81,85 @@ jobs:
sha: pr.data.head.sha
};
- name: Trigger all workflows and collect results
- name: Get skipped checks and trigger workflows
id: trigger_workflows
uses: actions/github-script@v7
with:
script: |
const prData = ${{ steps.pr.outputs.result }};
const workflows = [
'main.yml',
'examples.yml',
'pro-integration-tests.yml',
'pro-package-tests.yml'
];
// Fetch PR checks to find skipped ones
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
const checks = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: pr.head.sha,
per_page: 100
});
// Find all skipped checks
const skippedChecks = checks.data.check_runs.filter(check =>
check.conclusion === 'SKIPPED' && check.status === 'COMPLETED'
);
console.log(`Found ${skippedChecks.length} skipped checks:`);
skippedChecks.forEach(check => {
console.log(` - ${check.name} (${check.workflow_name})`);
});
// Map workflow names to workflow files
const workflowMap = {
'Main test': 'main.yml',
'Generator tests': 'examples.yml',
'React on Rails Pro - Integration Tests': 'pro-integration-tests.yml',
'React on Rails Pro - Package Tests': 'pro-package-tests.yml',
'React on Rails Pro - Lint': 'pro-lint.yml'
};
// Get unique workflows that have skipped checks
const uniqueWorkflows = new Set();
skippedChecks.forEach(check => {
if (workflowMap[check.workflow_name]) {
uniqueWorkflows.add(check.workflow_name);
}
});
const succeeded = [];
const failed = [];
const notApplicable = [];
// Trigger all workflows
for (const workflowId of workflows) {
// Trigger each workflow that has skipped checks
for (const workflowName of uniqueWorkflows) {
const workflowFile = workflowMap[workflowName];
try {
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflowId,
ref: prData.ref
workflow_id: workflowFile,
ref: prData.ref,
inputs: {
force_run: 'true'
}
});
console.log(`✅ Triggered ${workflowId}`);
succeeded.push(workflowId);
console.log(`✅ Triggered ${workflowFile} (${workflowName})`);
succeeded.push({ id: workflowFile, name: workflowName });
} catch (error) {
console.error(`❌ Failed to trigger ${workflowId}:`, error.message);
failed.push({ workflow: workflowId, error: error.message });
console.error(`❌ Failed to trigger ${workflowFile}:`, error.message);
failed.push({ workflow: workflowName, error: error.message });
}
}
// Note workflows with no skipped checks
if (uniqueWorkflows.size === 0) {
console.log('ℹ️ No skipped checks found - all tests already running on this PR');
notApplicable.push('No skipped checks to run');
}
// Wait a bit for workflows to queue
if (succeeded.length > 0) {
console.log('Waiting 5 seconds for workflows to queue...');
Expand All @@ -132,48 +178,55 @@ jobs:
created: `>${new Date(Date.now() - 60000).toISOString()}`
});
for (const workflowId of succeeded) {
for (const workflow of succeeded) {
const found = runs.data.workflow_runs.some(run =>
run.path === `.github/workflows/${workflowId}` &&
run.path === `.github/workflows/${workflow.id}` &&
run.head_sha === prData.sha &&
run.event === 'workflow_dispatch'
);
if (found) {
verified.push(workflowId);
verified.push(workflow);
} else {
notFound.push(workflowId);
notFound.push(workflow);
}
}
}
// Build the comment body based on actual results
let status = '✅ **Successfully triggered and verified all workflows**';
if (failed.length > 0 && notFound.length > 0) {
let status;
if (notApplicable.length > 0) {
status = '✅ **All checks are already running - nothing to do!**';
} else if (failed.length > 0 && notFound.length > 0) {
status = '❌ **Failed to trigger or verify workflows**';
} else if (failed.length > 0) {
status = '⚠️ **Some workflows failed to trigger**';
} else if (notFound.length > 0) {
status = '⚠️ **Workflows triggered but not yet verified**';
} else {
status = '✅ **Successfully triggered skipped CI checks**';
}
const verifiedList = verified.length > 0 ? verified.map(w => `- ✅ ${w}`).join('\n') : '';
const notFoundList = notFound.length > 0 ? `\n\n**Triggered but not yet queued (may still start):**\n${notFound.map(w => `- ⏳ ${w}`).join('\n')}` : '';
// List the skipped checks we found
const skippedChecksList = skippedChecks.length > 0
? `\n**Skipped checks detected:**\n${skippedChecks.map(c => `- ${c.name} (${c.workflow_name})`).join('\n')}`
: '';
const verifiedList = verified.length > 0 ? `\n**Triggered workflows:**\n${verified.map(w => `- ✅ ${w.name}`).join('\n')}` : '';
const notFoundList = notFound.length > 0 ? `\n\n**Triggered but not yet queued (may still start):**\n${notFound.map(w => `- ⏳ ${w.name}`).join('\n')}` : '';
const failedList = failed.length > 0 ? `\n\n**Failed to trigger:**\n${failed.map(f => `- ❌ ${f.workflow}: ${f.error}`).join('\n')}` : '';
const body = `🚀 **Full CI Suite Results**
const body = `🚀 **Skipped CI Checks - Trigger Results**
${status}
${skippedChecksList}
${verifiedList}${notFoundList}${failedList}
${verifiedList ? `**Verified workflows:**\n${verifiedList}` : ''}${notFoundList}${failedList}
${verified.length > 0 ? `\n**Note:** These workflows will run with \`force_run: true\` to bypass detect-changes logic that caused them to skip.
${verified.length > 0 ? `\nThese will run all CI jobs including those normally skipped on PRs:
- ✅ Minimum dependency versions (Ruby 3.2, Node 20)
- ✅ All example app tests
- ✅ Pro package integration tests
- ✅ Pro package unit tests
View progress in the [Actions tab](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions).` : ''}
View progress in the [Actions tab](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions).` : ''}`;
${notApplicable.length > 0 ? `\nAll CI checks are already running on this PR. Use this command when you see skipped checks that you want to run.` : ''}`;
// Post the comment
await github.rest.issues.createComment({
Expand Down