Skip to content

Commit aac7121

Browse files
justin808claude
andcommitted
Improve full-ci label implementation with better output handling and UX
This commit enhances the /run-skipped-ci feature based on code review feedback: **Critical Fixes:** - Fix GitHub Actions output encoding to use explicit string values - Add result-encoding: string to all label check steps - Return 'true'/'false' strings instead of booleans for consistent shell comparison - Fixes potential silent failures in label detection across 6 workflow files **New Features:** - Add automatic full-ci label cleanup when PRs are merged - Add welcome message to new PRs explaining CI control commands - Comprehensive documentation in CONTRIBUTING.md **Files Changed:** - .github/workflows/main.yml - Fixed output encoding - .github/workflows/examples.yml - Fixed output encoding - .github/workflows/pro-*.yml (3 files) - Fixed output encoding - .github/workflows/cleanup-full-ci-label.yml - New: Auto-remove label on merge - .github/workflows/pr-welcome-message.yml - New: Welcome message for PRs - CONTRIBUTING.md - Added CI Control Commands documentation The full-ci label now persists correctly across commits and provides clear user guidance through automated messages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 1015fe9 commit aac7121

File tree

8 files changed

+144
-10
lines changed

8 files changed

+144
-10
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Cleanup full-ci label on PR merge
2+
3+
on:
4+
pull_request:
5+
types: [closed]
6+
7+
jobs:
8+
remove-label:
9+
# Only run when PR is actually merged (not just closed)
10+
if: github.event.pull_request.merged == true
11+
runs-on: ubuntu-22.04
12+
permissions:
13+
issues: write
14+
pull-requests: write
15+
steps:
16+
- name: Remove full-ci label
17+
uses: actions/github-script@v7
18+
with:
19+
script: |
20+
try {
21+
await github.rest.issues.removeLabel({
22+
owner: context.repo.owner,
23+
repo: context.repo.repo,
24+
issue_number: context.issue.number,
25+
name: 'full-ci'
26+
});
27+
console.log('✅ Removed full-ci label from merged PR');
28+
} catch (error) {
29+
if (error.status === 404) {
30+
console.log('ℹ️ Label not present - nothing to clean up');
31+
} else {
32+
console.error('⚠️ Failed to remove label:', error.message);
33+
// Don't fail the workflow - this is just cleanup
34+
}
35+
}

.github/workflows/examples.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ jobs:
4040
id: check-label
4141
uses: actions/github-script@v7
4242
with:
43+
result-encoding: string
4344
script: |
4445
// Only check labels on pull requests
4546
if (!context.payload.pull_request) {
46-
return false;
47+
return 'false';
4748
}
4849
4950
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
@@ -54,7 +55,7 @@ jobs:
5455
5556
const hasLabel = labels.some(label => label.name === 'full-ci');
5657
console.log(`full-ci label present: ${hasLabel}`);
57-
return hasLabel;
58+
return hasLabel ? 'true' : 'false';
5859
- name: Detect relevant changes
5960
id: detect
6061
run: |

.github/workflows/main.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ jobs:
4040
id: check-label
4141
uses: actions/github-script@v7
4242
with:
43+
result-encoding: string
4344
script: |
4445
// Only check labels on pull requests
4546
if (!context.payload.pull_request) {
46-
return false;
47+
return 'false';
4748
}
4849
4950
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
@@ -54,7 +55,7 @@ jobs:
5455
5556
const hasLabel = labels.some(label => label.name === 'full-ci');
5657
console.log(`full-ci label present: ${hasLabel}`);
57-
return hasLabel;
58+
return hasLabel ? 'true' : 'false';
5859
- name: Detect relevant changes
5960
id: detect
6061
run: |
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name: PR Welcome Message
2+
3+
on:
4+
pull_request:
5+
types: [opened]
6+
7+
jobs:
8+
welcome:
9+
runs-on: ubuntu-22.04
10+
permissions:
11+
issues: write
12+
pull-requests: write
13+
steps:
14+
- name: Post welcome message
15+
uses: actions/github-script@v7
16+
with:
17+
script: |
18+
const welcomeMessage = [
19+
'👋 **Thanks for your contribution!**',
20+
'',
21+
'This PR will run CI tests based on the files you changed. If some tests are skipped and you want to run the full test suite (including minimum dependency tests), you can use these commands:',
22+
'',
23+
'### CI Control Commands',
24+
'',
25+
'- **`/run-skipped-ci`** - Runs all skipped CI checks and enables full CI mode for this PR',
26+
' - Adds the `full-ci` label to ensure future commits also run the full test suite',
27+
' - Useful when you want comprehensive testing across all configurations',
28+
'',
29+
'- **`/stop-run-skipped-ci`** - Disables full CI mode and returns to standard CI',
30+
' - Removes the `full-ci` label',
31+
' - Future commits will only run tests for changed files',
32+
'',
33+
'💡 **Note:** The `full-ci` label will be automatically removed when this PR is merged.',
34+
'',
35+
'View CI progress in the [Actions tab](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions).'
36+
].join('\n');
37+
38+
await github.rest.issues.createComment({
39+
owner: context.repo.owner,
40+
repo: context.repo.repo,
41+
issue_number: context.issue.number,
42+
body: welcomeMessage
43+
});
44+
45+
console.log('✅ Posted welcome message to PR');

.github/workflows/pro-integration-tests.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ jobs:
3434
id: check-label
3535
uses: actions/github-script@v7
3636
with:
37+
result-encoding: string
3738
script: |
3839
// Only check labels on pull requests
3940
if (!context.payload.pull_request) {
40-
return false;
41+
return 'false';
4142
}
4243
4344
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
@@ -48,7 +49,7 @@ jobs:
4849
4950
const hasLabel = labels.some(label => label.name === 'full-ci');
5051
console.log(`full-ci label present: ${hasLabel}`);
51-
return hasLabel;
52+
return hasLabel ? 'true' : 'false';
5253
- name: Detect relevant changes
5354
id: detect
5455
working-directory: .

.github/workflows/pro-lint.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ jobs:
3434
id: check-label
3535
uses: actions/github-script@v7
3636
with:
37+
result-encoding: string
3738
script: |
3839
// Only check labels on pull requests
3940
if (!context.payload.pull_request) {
40-
return false;
41+
return 'false';
4142
}
4243
4344
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
@@ -48,7 +49,7 @@ jobs:
4849
4950
const hasLabel = labels.some(label => label.name === 'full-ci');
5051
console.log(`full-ci label present: ${hasLabel}`);
51-
return hasLabel;
52+
return hasLabel ? 'true' : 'false';
5253
- name: Detect relevant changes
5354
id: detect
5455
working-directory: .

.github/workflows/pro-package-tests.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,11 @@ jobs:
3434
id: check-label
3535
uses: actions/github-script@v7
3636
with:
37+
result-encoding: string
3738
script: |
3839
// Only check labels on pull requests
3940
if (!context.payload.pull_request) {
40-
return false;
41+
return 'false';
4142
}
4243
4344
const { data: labels } = await github.rest.issues.listLabelsOnIssue({
@@ -48,7 +49,7 @@ jobs:
4849
4950
const hasLabel = labels.some(label => label.name === 'full-ci');
5051
console.log(`full-ci label present: ${hasLabel}`);
51-
return hasLabel;
52+
return hasLabel ? 'true' : 'false';
5253
- name: Detect relevant changes
5354
id: detect
5455
working-directory: .

CONTRIBUTING.md

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,55 @@ The CI system intelligently skips unnecessary work:
421421

422422
For more details, see [`docs/CI_OPTIMIZATION.md`](./docs/CI_OPTIMIZATION.md).
423423

424+
### CI Control Commands
425+
426+
React on Rails provides PR comment commands to control CI behavior:
427+
428+
#### `/run-skipped-ci` - Enable Full CI Mode
429+
430+
Runs all skipped CI checks and enables full CI mode for the PR:
431+
432+
```
433+
/run-skipped-ci
434+
```
435+
436+
**What it does:**
437+
438+
- Triggers all CI workflows that were skipped due to unchanged code
439+
- Adds the `full-ci` label to the PR
440+
- **Persists across future commits** - all subsequent pushes will run the full test suite
441+
- Runs minimum dependency tests (Ruby 3.2, Node 20, Shakapacker 8.2.0, React 18)
442+
443+
**When to use:**
444+
445+
- You want comprehensive testing across all configurations
446+
- Testing changes that might affect minimum supported versions
447+
- Validating generator changes or core functionality
448+
- Before merging PRs that touch critical paths
449+
450+
#### `/stop-run-skipped-ci` - Disable Full CI Mode
451+
452+
Removes the `full-ci` label and returns to standard CI behavior:
453+
454+
```
455+
/stop-run-skipped-ci
456+
```
457+
458+
**What it does:**
459+
460+
- Removes the `full-ci` label from the PR
461+
- Future commits will use the optimized CI suite (tests only changed code)
462+
- Does not stop currently running workflows
463+
464+
**When to use:**
465+
466+
- You've validated changes with full CI and want to return to faster feedback
467+
- Reducing CI time during rapid iteration on a PR
468+
469+
#### Automatic Cleanup
470+
471+
The `full-ci` label is automatically removed when a PR is merged, so you don't need to manually clean it up.
472+
424473
### Install Generator
425474

426475
In your Rails app add this gem with a path to your fork.

0 commit comments

Comments
 (0)