Skip to content

Fix /run-skipped-ci command to only run minimum dependency tests #18

Fix /run-skipped-ci command to only run minimum dependency tests

Fix /run-skipped-ci command to only run minimum dependency tests #18

name: Run Full CI Suite
on:
issue_comment:
types: [created]
# Prevent concurrent runs per PR
concurrency:
group: full-ci-${{ github.event.issue.number }}
cancel-in-progress: true
jobs:
trigger-full-ci:
# Only run on PR comments that match the command
if: |
github.event.issue.pull_request &&
(
startsWith(github.event.comment.body, '/run-skipped-ci') ||
contains(github.event.comment.body, '\n/run-skipped-ci')
)
runs-on: ubuntu-22.04
permissions:
contents: read
pull-requests: write
actions: 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 trigger 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 trigger 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: 'rocket'
- name: Get PR details
id: pr
uses: actions/github-script@v7
with:
script: |
const pr = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: context.issue.number
});
return {
ref: pr.data.head.ref,
sha: pr.data.head.sha
};
- name: Trigger all workflows and collect results
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'
];
const succeeded = [];
const failed = [];
// Trigger all workflows
for (const workflowId of workflows) {
try {
await github.rest.actions.createWorkflowDispatch({
owner: context.repo.owner,
repo: context.repo.repo,
workflow_id: workflowId,
ref: prData.ref
});
console.log(`✅ Triggered ${workflowId}`);
succeeded.push(workflowId);
} catch (error) {
console.error(`❌ Failed to trigger ${workflowId}:`, error.message);
failed.push({ workflow: workflowId, error: error.message });
}
}
// Wait a bit for workflows to queue
if (succeeded.length > 0) {
console.log('Waiting 5 seconds for workflows to queue...');
await new Promise(resolve => setTimeout(resolve, 5000));
}
// Verify workflows are queued/running
const verified = [];
const notFound = [];
if (succeeded.length > 0) {
const runs = await github.rest.actions.listWorkflowRunsForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
created: `>${new Date(Date.now() - 60000).toISOString()}`
});
for (const workflowId of succeeded) {
const found = runs.data.workflow_runs.some(run =>
run.path === `.github/workflows/${workflowId}` &&
run.head_sha === prData.sha &&
run.event === 'workflow_dispatch'
);
if (found) {
verified.push(workflowId);
} else {
notFound.push(workflowId);
}
}
}
// Build the comment body based on actual results
let status = '✅ **Successfully triggered and verified all workflows**';
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**';
}
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')}` : '';
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**
${status}
${verifiedList ? `**Verified workflows:**\n${verifiedList}` : ''}${notFoundList}${failedList}
${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).` : ''}`;
// Post the comment
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: body
});
// Fail the job if any workflows failed to trigger
if (failed.length > 0) {
core.setFailed(`Failed to trigger ${failed.length} workflow(s): ${failed.map(f => f.workflow).join(', ')}`);
}