Skip to content

feat: use total_count field from Pagination API response #399

feat: use total_count field from Pagination API response

feat: use total_count field from Pagination API response #399

Workflow file for this run

name: PR Title Check
on:
pull_request:
types: [opened, edited, synchronize, reopened]
workflow_dispatch:
jobs:
pr-title-check:
runs-on: ubuntu-slim
steps:
- name: Validate PR title
uses: actions/github-script@v7
with:
script: |
// Fetch current PR to always get latest title, even on workflow re-runs
const prNumber = context.issue.number || context.payload.pull_request?.number;
if (!prNumber) {
core.setFailed('Unable to determine PR number');
return;
}
const { data: pr } = await github.rest.pulls.get({
owner: context.repo.owner,
repo: context.repo.repo,
pull_number: prNumber
});
const title = pr.title;
console.log(`Validating PR title: "${title}"`);
// Define allowed types
const types = [
'feat', 'fix', 'docs', 'style', 'refactor',
'perf', 'test', 'build', 'ci', 'chore', 'revert'
];
// Define allowed scopes (optional)
const scopes = [
'cli', 'mcp', 'devbox', 'benchmark', 'secret',
'blueprint', 'storage-object', 'network-policy',
'main', 'snapshot', 'config', 'auth', 'deps'
];
// Regex pattern: type(scope)?: description
// type is required, scope is optional, description must start with lowercase
const pattern = /^(feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert)(\([a-z0-9-]+\))?:\s*[a-z].+$/;
if (!pattern.test(title)) {
const errorMsg = [
'❌ PR title does not follow the conventional commit format.',
'',
`Found: "${title}"`,
'',
'Expected format: type(scope)?: description',
'',
'Where:',
`- type: one of ${types.join(', ')}`,
`- scope (optional): one of ${scopes.join(', ')}`,
'- description: starts with a lowercase letter',
'',
'Examples:',
'- feat: add new devbox command',
'- fix(cli): resolve argument parsing issue',
'- docs: update README with usage examples',
'- feat(network-policy): add support for gateway flags'
].join('\n');
core.setFailed(errorMsg);
return;
}
// Extract and validate scope if present
const scopeMatch = title.match(/\(([^)]+)\)/);
if (scopeMatch) {
const scope = scopeMatch[1];
if (!scopes.includes(scope)) {
core.setFailed(
`❌ Invalid scope "${scope}".\n\nAllowed scopes: ${scopes.join(', ')}`
);
return;
}
}
console.log('✅ PR title is valid!');