Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dependabot PRs result in an empty release #1

Closed
NicholasBoll opened this issue Jun 20, 2022 · 1 comment · Fixed by #2
Closed

Dependabot PRs result in an empty release #1

NicholasBoll opened this issue Jun 20, 2022 · 1 comment · Fixed by #2
Labels
enhancement New feature or request

Comments

@NicholasBoll
Copy link
Member

NicholasBoll commented Jun 20, 2022

We ignore PR lint rules for dependabot PRs because they are autogenerated, but this causes empty releases because this causes empty merge messages.

For example, the release notes are empty: https://github.com/Workday/canvas-kit/releases/tag/v7.0.13

Here's the PR: Workday/canvas-kit#1492

The dependabot PRs lack the normally required "sections" (category and summary). The utility function that needs to be updated is the getSections found here:

export function getSections(input: string): Sections {
let activeSection: keyof Sections | '' = ''
const sections = input
.replace(/\r/g, '')
.split('\n')
.reduce((result, line) => {
const headingMatch = line.match(/^#+\s+(.+)/)
const badgeMatch = line.match(
/^!\[[a-z]+\]\(https:\/\/img.shields.io\/badge\/([a-z_]+)-([a-z_]+)-[a-z]+\)/i,
)
if (headingMatch) {
const heading = headingMatch[1].trim().toLowerCase()
if (isValidHeading(heading)) {
activeSection = heading
result[activeSection] = ''
} else {
// Deactivate active section until a new one is found
activeSection = ''
}
} else if (badgeMatch) {
const heading = badgeMatch[1].replace(/_/g, ' ').trim()
const value = badgeMatch[2].replace(/_/g, ' ').trim()
if (isValidHeading(heading)) {
result[heading] = value
// we're done with this heading, deactivate the section
activeSection = ''
}
} else {
// A horizontal rule will break out of a section
if (line.trim() === '---') {
activeSection = ''
}
if (activeSection) {
result[activeSection] += `\n${line}`
}
}
return result
}, {} as Sections)
// trim sections and remove comments
for (const [key, value] of Object.entries(sections)) {
sections[key as keyof Sections] = value
.replace(/<!--[\s\S]+?-->/gm, '') // replace comments non-greedily in multiline mode
.replace(/[\n]{2,}/g, '\n\n') // assume more than 2 newlines in a row are a mistake, perhaps from removing comments
.trim()
}
return sections
}

The tests for getSections are unit tests found here:

describe('getSections', () => {
it('should parse headings into sections', () => {
const input = stripIndent`
## Summary
My summary
## Release Category
Components
## Release Note
My release notes
### BREAKING CHANGES
Some breaking changes
`
const expected = {
summary: 'My summary',
'release category': 'Components',
'release note': 'My release notes',
'breaking changes': 'Some breaking changes',
}
expect(getSections(input)).toEqual(expected)
})
it('should parse headings and a category shield', () => {
const input = stripIndent`
## Summary
My summary
![category](https://img.shields.io/badge/release_category-Components-blue)
## Release Note
My release notes
### BREAKING CHANGES
Some breaking changes
`
const expected = {
summary: 'My summary',
'release category': 'Components',
'release note': 'My release notes',
'breaking changes': 'Some breaking changes',
}
expect(getSections(input)).toEqual(expected)
})
})
describe('getCommitParts', () => {
// it('should leave the ')
it('should extract the parts of a commit message', () => {
const input = stripIndent`
feat(tooltip): Fix OverflowTooltip with SVG icons in IE11 (#1234)
My summary
[category:Components]
Release Note:
My release notes
### BREAKING CHANGES
Some breaking changes
`
const expected = {
title: 'feat(tooltip): Fix OverflowTooltip with SVG icons in IE11',
pull_request: '1234',
category: 'Components',
'release note': 'My release notes',
'breaking change': 'Some breaking changes',
}
expect(getCommitParts(input)).toEqual(expected)
})
it('should remove the breaking indicator from the title', () => {
const input = stripIndent`
feat(tooltip)!: Fix OverflowTooltip with SVG icons in IE11 (#1234)
`
const expected = {
title: 'feat(tooltip): Fix OverflowTooltip with SVG icons in IE11',
pull_request: '1234',
category: 'Components',
}
expect(getCommitParts(input)).toEqual(expected)
})
it('should guess that "ci:" is infrastructure', () => {
const input = stripIndent`
ci: Upgrade to Github Actions (#1234)
My summary
`
const expected = {
title: 'ci: Upgrade to Github Actions',
pull_request: '1234',
category: 'Infrastructure',
}
expect(getCommitParts(input)).toEqual(expected)
})
})

The tests are set up the following way:

  • input: The PR body. The contents of a Dependabot PR could be copy/pasted into the test
  • expected: The sections that will be passed to create a merge title and body

For example, the linked PR should produce an expected sections like the following:

      const expected = {
        summary: 'Bumps [prismjs](https://github.com/PrismJS/prism) from 1.25.0 to 1.27.0.',
        'release category': 'Dependencies',
      }

No other code needs to be updated other than utils.ts and utils.test.ts which means the code should be 100% unit tested without worry our CI will crash!

@NicholasBoll NicholasBoll added the enhancement New feature or request label Jun 20, 2022
@NicholasBoll
Copy link
Member Author

Here's the test that should pass:

    it('should parse dependabot pull requests', () => {
      const input = stripIndent`
      Bumps [prismjs](https://github.com/PrismJS/prism) from 1.25.0 to 1.27.0.
      <details>
      <summary>Release notes</summary>
      <p><em>Sourced from <a href="https://github.com/PrismJS/prism/releases">prismjs's releases</a>.</em></p>
      <blockquote>
      <h2>v1.27.0</h2>
      <p>Release 1.27.0</p>
      <h2>v1.26.0</h2>
      <p>Release 1.26.0</p>
      </blockquote>
      </details>

      [![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prismjs&package-manager=npm_and_yarn&previous-version=1.25.0&new-version=1.27.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

      Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting \`@dependabot rebase\`.

      [//]: # (dependabot-automerge-start)
      [//]: # (dependabot-automerge-end)

      ---

      <details>
      <summary>Dependabot commands and options</summary>
      <br />
      You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/Workday/canvas-kit/network/alerts).
      </details>
      `

      const expected = {
        summary: 'Bumps [prismjs](https://github.com/PrismJS/prism) from 1.25.0 to 1.27.0.',
        'release category': 'Dependencies',
      }

      expect(getSections(input)).toEqual(expected)
    })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant