Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
30 changes: 25 additions & 5 deletions .github/workflows/examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,37 @@ jobs:
run_ruby_tests: ${{ steps.detect.outputs.run_ruby_tests }}
run_dummy_tests: ${{ steps.detect.outputs.run_dummy_tests }}
run_generators: ${{ steps.detect.outputs.run_generators }}
has_full_ci_label: ${{ steps.check-label.outputs.has_label }}
steps:
- uses: actions/checkout@v4
with:
# Fetch enough history for change detection (50 commits is usually sufficient for PRs)
fetch-depth: 50
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: actions/github-script@v7
with:
script: |
// Only check labels on pull requests
if (!context.payload.pull_request) {
return false;
}

const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});

const hasLabel = labels.some(label => label.name === 'full-ci');
console.log(`full-ci label present: ${hasLabel}`);
return hasLabel;
- name: Detect relevant changes
id: detect
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
# If force_run is true OR full-ci label is present, run everything
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_lint=true" >> "$GITHUB_OUTPUT"
echo "run_js_tests=true" >> "$GITHUB_OUTPUT"
echo "run_ruby_tests=true" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -69,9 +89,9 @@ jobs:
- ruby-version: '3.2'
dependency-level: 'minimum'
exclude:
# 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' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run/full-ci label)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && '3.2' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && 'minimum' || '' }}
env:
SKIP_YARN_COREPACK_CHECK: 0
BUNDLE_FROZEN: ${{ matrix.dependency-level == 'minimum' && 'false' || 'true' }}
Expand Down
40 changes: 30 additions & 10 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,37 @@ jobs:
run_ruby_tests: ${{ steps.detect.outputs.run_ruby_tests }}
run_dummy_tests: ${{ steps.detect.outputs.run_dummy_tests }}
run_generators: ${{ steps.detect.outputs.run_generators }}
has_full_ci_label: ${{ steps.check-label.outputs.has_label }}
steps:
- uses: actions/checkout@v4
with:
# Fetch enough history for change detection (50 commits is usually sufficient for PRs)
fetch-depth: 50
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: actions/github-script@v7
with:
script: |
// Only check labels on pull requests
if (!context.payload.pull_request) {
return false;
}

const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});

const hasLabel = labels.some(label => label.name === 'full-ci');
console.log(`full-ci label present: ${hasLabel}`);
return hasLabel;
- name: Detect relevant changes
id: detect
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
# If force_run is true OR full-ci label is present, run everything
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_lint=true" >> "$GITHUB_OUTPUT"
echo "run_js_tests=true" >> "$GITHUB_OUTPUT"
echo "run_ruby_tests=true" >> "$GITHUB_OUTPUT"
Expand Down Expand Up @@ -70,10 +90,10 @@ jobs:
node-version: '20'
dependency-level: 'minimum'
exclude:
# 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' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run/full-ci label)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && 'minimum' || '' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -160,10 +180,10 @@ jobs:
node-version: '20'
dependency-level: 'minimum'
exclude:
# 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' || '' }}
# Skip minimum dependency matrix on regular PRs (run only on master/workflow_dispatch/force_run/full-ci label)
- ruby-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && '3.2' || '' }}
node-version: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && '20' || '' }}
dependency-level: ${{ github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && inputs.force_run != true && needs.detect-changes.outputs.has_full_ci_label != 'true' && 'minimum' || '' }}
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
Expand Down
24 changes: 22 additions & 2 deletions .github/workflows/pro-integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,37 @@ jobs:
docs_only: ${{ steps.detect.outputs.docs_only }}
run_pro_lint: ${{ steps.detect.outputs.run_pro_lint }}
run_pro_tests: ${{ steps.detect.outputs.run_pro_tests }}
has_full_ci_label: ${{ steps.check-label.outputs.has_label }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: actions/github-script@v7
with:
script: |
// Only check labels on pull requests
if (!context.payload.pull_request) {
return false;
}

const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});

const hasLabel = labels.some(label => label.name === 'full-ci');
console.log(`full-ci label present: ${hasLabel}`);
return hasLabel;
- name: Detect relevant changes
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
# If force_run is true OR full-ci label is present, run everything
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
Expand Down
24 changes: 22 additions & 2 deletions .github/workflows/pro-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,37 @@ jobs:
docs_only: ${{ steps.detect.outputs.docs_only }}
run_pro_lint: ${{ steps.detect.outputs.run_pro_lint }}
run_pro_tests: ${{ steps.detect.outputs.run_pro_tests }}
has_full_ci_label: ${{ steps.check-label.outputs.has_label }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: actions/github-script@v7
with:
script: |
// Only check labels on pull requests
if (!context.payload.pull_request) {
return false;
}

const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});

const hasLabel = labels.some(label => label.name === 'full-ci');
console.log(`full-ci label present: ${hasLabel}`);
return hasLabel;
- name: Detect relevant changes
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
# If force_run is true OR full-ci label is present, run everything
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
Expand Down
24 changes: 22 additions & 2 deletions .github/workflows/pro-package-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,37 @@ jobs:
docs_only: ${{ steps.detect.outputs.docs_only }}
run_pro_lint: ${{ steps.detect.outputs.run_pro_lint }}
run_pro_tests: ${{ steps.detect.outputs.run_pro_tests }}
has_full_ci_label: ${{ steps.check-label.outputs.has_label }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: actions/github-script@v7
with:
script: |
// Only check labels on pull requests
if (!context.payload.pull_request) {
return false;
}

const { data: labels } = await github.rest.issues.listLabelsOnIssue({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.payload.pull_request.number
});

const hasLabel = labels.some(label => label.name === 'full-ci');
console.log(`full-ci label present: ${hasLabel}`);
return hasLabel;
- name: Detect relevant changes
id: detect
working-directory: .
run: |
# If force_run is true, run everything
if [ "${{ inputs.force_run }}" = "true" ]; then
# If force_run is true OR full-ci label is present, run everything
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_pro_lint=true" >> "$GITHUB_OUTPUT"
echo "run_pro_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
Expand Down
20 changes: 17 additions & 3 deletions .github/workflows/run-skipped-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ jobs:
sha: pr.data.head.sha
};

- name: Add full-ci label
uses: actions/github-script@v7
with:
script: |
await github.rest.issues.addLabels({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
labels: ['full-ci']
});
console.log('✅ Added full-ci label to PR');

- name: Get skipped checks and trigger workflows
id: trigger_workflows
uses: actions/github-script@v7
Expand Down Expand Up @@ -216,17 +228,19 @@ jobs:
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 = `🚀 **Skipped CI Checks - Trigger Results**
const body = `🚀 **Full CI Mode Enabled**

${status}
${skippedChecksList}
${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 ? `\n**Note:** Added the \`full-ci\` label to this PR. All future commits will run the full CI suite (including minimum dependency tests) until the label is removed.

To disable full CI mode, use the \`/stop-run-skipped-ci\` command.

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.` : ''}`;
${notApplicable.length > 0 ? `\nAll CI checks are already running on this PR. The \`full-ci\` label has been added - future commits will run the full CI suite.` : ''}`;

// Post the comment
await github.rest.issues.createComment({
Expand Down
111 changes: 111 additions & 0 deletions .github/workflows/stop-run-skipped-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: Stop Full CI Suite

on:
issue_comment:
types: [created]

jobs:
stop-full-ci:
# Only run on PR comments that match the command
if: |
github.event.issue.pull_request &&
(
startsWith(github.event.comment.body, '/stop-run-skipped-ci') ||
contains(github.event.comment.body, '\n/stop-run-skipped-ci')
)
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: write
issues: write
steps:
- name: Check if user has write access
id: check_access
uses: actions/github-script@v7
with:
script: |
try {
const { data: permission } = await github.rest.repos.getCollaboratorPermissionLevel({
owner: context.repo.owner,
repo: context.repo.repo,
username: context.actor
});
const hasAccess = ['admin', 'write'].includes(permission.permission);
console.log(`User ${context.actor} has permission: ${permission.permission}`);
if (!hasAccess) {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `@${context.actor} Sorry, only repository collaborators with write access can stop full CI runs. 🔒`
});
}
return hasAccess;
} catch (error) {
console.error('Error checking permissions:', error);
return false;
}
- name: Exit if no access
if: steps.check_access.outputs.result == 'false'
run: |
echo "User does not have permission to stop full CI"
exit 1
- name: Add reaction to comment
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ github.event.comment.id }}
reactions: 'eyes'

- name: Remove full-ci label
uses: actions/github-script@v7
with:
script: |
try {
await github.rest.issues.removeLabel({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
name: 'full-ci'
});
console.log('✅ Removed full-ci label from PR');
// Post success comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `✅ **Full CI Mode Disabled**
The \`full-ci\` label has been removed. Future commits will use the standard CI suite (skipping tests for unchanged code).

To re-enable full CI mode, use the \`/run-skipped-ci\` command.`
});
} catch (error) {
if (error.status === 404) {
console.log('ℹ️ Label not found - already removed or never added');
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `ℹ️ **Full CI Mode Already Disabled**
The \`full-ci\` label is not present on this PR. CI is already running in standard mode.`
});
} else {
console.error('❌ Failed to remove label:', error);
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: `❌ **Error Removing Label**
Failed to remove the \`full-ci\` label: ${error.message}`
});
throw error;
}
}
Loading