diff --git a/__tests__/infrastructure/infra-change.test.js b/__tests__/infrastructure/infra-change.test.js new file mode 100644 index 0000000..72e560b --- /dev/null +++ b/__tests__/infrastructure/infra-change.test.js @@ -0,0 +1,79 @@ +const rule = require('../../src/rules/infrastructure/infra-change'); + +describe('Infra Change Rule', () => { + it('labels for terraform files', () => { + const files = [{ filename: 'infra/main.tf' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for terraform variables', () => { + const files = [{ filename: 'terraform/vars.tfvars' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for HCL files', () => { + const files = [{ filename: 'config/setup.hcl' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for docker-compose', () => { + const files = [{ filename: 'docker-compose.yml' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for Dockerfile', () => { + const files = [{ filename: 'services/Dockerfile' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for infra directory', () => { + const files = [{ filename: 'infrastructure/setup.yaml' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for k8s directory', () => { + const files = [{ filename: 'k8s/deployment.yaml' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for helm charts', () => { + const files = [{ filename: 'charts/app/values.yaml' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('labels for config directory', () => { + const files = [{ filename: 'config/production.yml' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toContain('infra-change'); + }); + + it('does not label for app code', () => { + const files = [{ filename: 'src/app.js' }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toEqual([]); + }); + + it('handles empty files array', () => { + const labels = rule({ files: [], pr: {}, enableDebug: false }); + expect(labels).toEqual([]); + }); + + it('handles null filename', () => { + const files = [{ filename: null }]; + const labels = rule({ files, pr: {}, enableDebug: false }); + expect(labels).toEqual([]); + }); + + it('handles debug mode', () => { + const files = [{ filename: 'infra/main.tf' }]; + expect(() => rule({ files, pr: {}, enableDebug: true })).not.toThrow(); + }); +}); diff --git a/src/rules/infrastructure/infra-change.js b/src/rules/infrastructure/infra-change.js new file mode 100644 index 0000000..3b8c0cf --- /dev/null +++ b/src/rules/infrastructure/infra-change.js @@ -0,0 +1,45 @@ +/** + * Infrastructure Config Change Rule + * + * Adds `infra-change` if infra-related files are modified. + */ + +module.exports = function infraChangeRule({ files, pr, enableDebug }) { + const labels = []; + + const hints = [ + /^(infra|infrastructure|ops|deploy|deployment|k8s|helm|charts|terraform|ansible|chef|salt)\//i, + /^config\//i, + /\.(tf|tfvars|hcl|tpl)$/i, + /(^|\/)Dockerfile(\.|$)/i, + /(^|\/)docker-compose\.(ya?ml)$/i + ]; + + const detected = (files || []).some(f => { + const name = (f && f.filename ? String(f.filename) : '').toLowerCase(); + return name && hints.some(rx => rx.test(name)); + }); + + if (detected) { + labels.push('infra-change'); + } + + if (enableDebug) { + console.log(`[Infra Change Rule] → ${labels.join(', ') || 'none'}`); + } + + return labels; +}; + +module.exports.metadata = { + name: 'Infrastructure Config Changes', + description: 'Detects changes to infrastructure/configuration files', + labels: [ + { name: 'infra-change', color: '0075CA', description: 'Infrastructure/config changed' } + ], + author: 'pr-auto-labeler', + version: '1.0.0', + category: 'infrastructure' +}; + +