Skip to content

Replace manual Fibers with Async gem primitives for component streaming #370

Replace manual Fibers with Async gem primitives for component streaming

Replace manual Fibers with Async gem primitives for component streaming #370

name: Detect Invalid CI Commands
on:
issue_comment:
types: [created]
jobs:
detect-invalid-commands:
# Only run on PR comments that contain potential commands but don't match valid commands
if: |
github.event.issue.pull_request &&
(
contains(github.event.comment.body, '/ci') ||
contains(github.event.comment.body, '/run') ||
contains(github.event.comment.body, '/stop') ||
contains(github.event.comment.body, '/delete') ||
contains(github.event.comment.body, '/deploy') ||
contains(github.event.comment.body, '/help')
) &&
!contains(github.event.comment.body, '/run-skipped-ci') &&
!contains(github.event.comment.body, '/run-skipped-tests') &&
!contains(github.event.comment.body, '/stop-run-skipped-ci')
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: write
steps:
- name: Check for similar commands
id: check_command
uses: actions/github-script@v7
with:
script: |
const comment = context.payload.comment.body;
// Pattern to detect potential command attempts at the start of a line
// Matches: /ci*, /run*, /stop*, /delete*, /deploy*, /help* at beginning or after newline
const commandPattern = /(?:^|\n)\s*(\/(ci|run|stop|delete|deploy|help)[\w-]*)/gi;
const matches = [...comment.matchAll(commandPattern)];
if (matches.length === 0) {
console.log('No potential commands found at line start');
return { shouldRespond: false };
}
// Valid commands
const validCommands = ['/run-skipped-ci', '/run-skipped-tests', '/stop-run-skipped-ci'];
// Check if any command is invalid
const invalidCommands = matches
.map(m => m[1].toLowerCase())
.filter(cmd => !validCommands.includes(cmd));
if (invalidCommands.length > 0) {
console.log('Found invalid commands:', invalidCommands);
return {
shouldRespond: true,
invalidCommands: invalidCommands
};
}
return { shouldRespond: false };
result-encoding: string
- name: Post helpful comment
if: steps.check_command.outputs.result != '' && fromJSON(steps.check_command.outputs.result).shouldRespond == true
uses: actions/github-script@v7
env:
CHECK_RESULT: ${{ steps.check_command.outputs.result }}
with:
script: |
const result = JSON.parse(process.env.CHECK_RESULT);
const invalidCommands = result.invalidCommands || [];
const invalidCmdsList = invalidCommands.length > 0
? `\n\n**Invalid command(s) detected:** ${invalidCommands.map(cmd => \`\\\`${cmd}\\\`\`).join(', ')}`
: '';
const body = \`👋 It looks like you may have tried to use a CI command, but it doesn't match the available commands.${invalidCmdsList}
## Available GitHub Comment Commands
### 1. \\\`/run-skipped-ci\\\` (or \\\`/run-skipped-tests\\\`) - Enable Full CI Mode
Triggers all CI workflows that were skipped due to unchanged code.
**What it does:**
- Runs tests across all supported versions (Ruby 3.2-3.4, Node 20-22, Shakapacker 8-9, React 18-19)
- Adds the \\\`full-ci\\\` label to persist full testing on future commits
- Triggers: Main tests, Generator tests, and React on Rails Pro tests
**Requirements:**
- Must have write access to the repository
- Use at the start of a comment or after a newline
**Example:**
\\\`\\\`\\\`
/run-skipped-ci
# or use the shorter alias:
/run-skipped-tests
\\\`\\\`\\\`
---
### 2. \\\`/stop-run-skipped-ci\\\` - Disable Full CI Mode
Returns to standard CI behavior (optimized suite, skips tests for unchanged code).
**What it does:**
- Removes the \\\`full-ci\\\` label from the PR
- Future commits will use the fast feedback CI suite
- Does NOT stop currently running workflows
**Requirements:**
- Must have write access to the repository
**Example:**
\\\`\\\`\\\`
/stop-run-skipped-ci
\\\`\\\`\\\`
---
### 3. \\\`@claude\\\` - Claude Code AI Review
Invokes Claude Code AI to perform code review or answer questions.
**What it does:**
- Analyzes code changes and provides feedback
- Follows instructions specified in the comment
- Can read CI results on PRs
**Example:**
\\\`\\\`\\\`
@claude please review the error handling in this PR
\\\`\\\`\\\`
---
## Local CI Debugging
Instead of using comment commands, you can replicate CI failures locally:
**Check CI status:**
\\\`\\\`\\\`bash
gh pr view --json statusCheckRollup
\\\`\\\`\\\`
**Re-run only failed jobs:**
\\\`\\\`\\\`bash
bin/ci-rerun-failures
\\\`\\\`\\\`
**Run specific failed specs:**
\\\`\\\`\\\`bash
pbpaste | bin/ci-run-failed-specs # macOS
\\\`\\\`\\\`
**Switch between CI configurations:**
\\\`\\\`\\\`bash
bin/ci-switch-config minimum # Test with Ruby 3.2, Node 20, etc.
bin/ci-switch-config latest # Return to Ruby 3.4, Node 22, etc.
\\\`\\\`\\\`
---
📖 For more details, see the [Contributing Guide](https://github.com/shakacode/react_on_rails/blob/master/CONTRIBUTING.md#using-comment-commands-to-trigger-ci)\`;
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
// Add reaction to original comment
await github.rest.reactions.createForIssueComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: context.payload.comment.id,
content: 'eyes'
});