also looking at this
fix(pr): apply the security label so security-only can fire
#1409
4 files
+87
-60
| @@ -76,6 +76,46 @@ describe('pull request labels', () => { | ||
| 76 | 76 | expect(labels.filter(label => label === 'deps')).toHaveLength(1) |
| 77 | 77 | }) |
| 78 | 78 | |
| 79 | describe('security advisories', () => { | |
| 80 | /** An update that resolves a published advisory. */ | |
| 81 | const vulnerable: PackageUpdate = { | |
| 82 | ...update, | |
| 83 | securityAdvisories: [{ | |
| 84 | id: 'GHSA-xxxx-yyyy-zzzz', | |
| 85 | aliases: ['CVE-2026-0001'], | |
| 86 | severity: 'high', | |
| 87 | summary: 'Prototype pollution', | |
| 88 | url: 'https://github.com/advisories/GHSA-xxxx-yyyy-zzzz', | |
| 89 | }], | |
| 90 | } | |
| 91 | ||
| 92 | /** Resolve labels for a group carrying the advisory. */ | |
| 93 | function labelsForVulnerable(config: BuddyConfig): string[] { | |
| 94 | const buddy = new Buddy(config) | |
| 95 | // @ts-expect-error - accessing private method for testing | |
| 96 | return buddy.labelsFor({ ...group, updates: [vulnerable] }, new PullRequestGenerator(config)) | |
| 97 | } | |
| 98 | ||
| 99 | it('success case - labels a group that resolves an advisory', () => { | |
| 100 | // `security-only` auto-merge tests for this label, so while nothing | |
| 101 | // applied it that condition could never once fire. | |
| 102 | expect(labelsForVulnerable(baseConfig)).toContain('security') | |
| 103 | }) | |
| 104 | ||
| 105 | it('success case - honours a configured label name', () => { | |
| 106 | const labels = labelsForVulnerable({ ...baseConfig, security: { label: 'vulnerability' } }) | |
| 107 | ||
| 108 | expect(labels).toContain('vulnerability') | |
| 109 | expect(labels).not.toContain('security') | |
| 110 | }) | |
| 111 | ||
| 112 | it('failure case - a routine update is not labelled security', () => { | |
| 113 | // The old implementation matched package names that merely sounded | |
| 114 | // security-related, which mislabelled routine updates. | |
| 115 | expect(labelsFor(baseConfig)).not.toContain('security') | |
| 116 | }) | |
| 117 | }) | |
| 118 | ||
| 79 | 119 | it('edge case - a rule that does not match contributes nothing', () => { |
| 80 | 120 | const labels = labelsFor({ |
| 81 | 121 | ...baseConfig, |