standard-version icon indicating copy to clipboard operation
standard-version copied to clipboard

Dealing with Azure DevOps Squash Merge prefixes

Open derekgreer opened this issue 4 years ago • 14 comments

When using Azure DevOps' squash merge feature, it adds a prefix of "Merged PR {nnn}: " to the PR title which itself it taken from the title of the first commit message associated with the request. This of course breaks standard-version and requires developers to remember to click "Customize merge message" and delete the offending prefix.

Is there any way to customize standard-version to mitigate this issue to reduce the friction?

For example, if a regex of "Merged PR \{[0-9]+\}: " could be specified as an optionally occurring prefix to any conventional commits, this would prevent accidental merges without properly fixing up the commit title.

Related Azure DevOps issue

derekgreer avatar Dec 02 '20 13:12 derekgreer

Further link to discussion about this topic

ShpendKe avatar Jan 05 '21 13:01 ShpendKe

This is not only related to Azure. Also GitHub and Bitbucket add these commit messages to a PR. This leads standard-version to only increase the patch version, even if the PR contains a feature or breaking change.

mberrezak avatar Mar 05 '21 11:03 mberrezak

Same issue here

tbarlow12 avatar Apr 16 '21 19:04 tbarlow12

Same here. For now, my solution is to block any kind of merge strategy that creates a merge commit.

leandrocrs avatar May 21 '21 16:05 leandrocrs

Using the right headerPattern that can correctly parse either the merge message or the commit message I was able to workaround the issue:

echo "Merged PR 6359: fix(credit): delete split schedule" | npx conventional-commits-parser --header-pattern "(?:\\(Merged PR \\d+: \\))?([a-zA-Z]+)(?:\\(([\\w$\\.\\-*\\s]*)\\))?\\!?:(.*)" --header-correspondence 'type, scope, subject'
[
    {
        "type": "fix",
        "scope": "credit",
        "subject": " delete split schedule",
        "merge": null,
        "header": "Merged PR 6359: fix(credit): delete split schedule even if the contract was already closed - PREPROD",
        "body": null,
        "footer": null,
        "notes": [],
        "references": [],
        "mentions": [],
        "revert": null
    }
]

So here is my changelog.config,json file:

{
  "parserOpts": {
    "headerPattern": "(?:\\(Merged PR \\d+: \\))?([a-zA-Z]+)(?:\\(([\\w$\\.\\-*\\s]*)\\))?\\!?:(.*)",
    "headerCorrespondence": ["type", "scope", "subject"]
  }
}

demo: https://regex101.com/r/oQT2m0/1

GoMino avatar Feb 11 '22 22:02 GoMino

@GoMino do you mind posting a complete example? How do you set up standard-version to use your changelog.config.json file?

Tri125 avatar Aug 09 '22 16:08 Tri125

Here is the command I use to specify my config:

npx conventional-changelog --config changelog.config.json --context changelog.context.json -i CHANGELOG.md -s   

changelog.config.json

{
  "options": {
    "preset": {
      "name": "conventionalcommits",
      "issuePrefixes": ["XX-", "XRUN-", "XRAY-"],
      "issueUrlFormat": "https://****/browse/{{prefix}}{{id}}",
      "commitUrlFormat": "{{host}}/{{owner}}/{{repository}}/commit/{{hash}}",
      "compareUrlFormat": "{{host}}/{{owner}}/{{repository}}/branchCompare?baseVersion=GT{{previousTag}}&targetVersion=GT{{currentTag}}&_a=commits",
      "types": [
        { "type": "feat", "section": "Features" },
        { "type": "feature", "section": "Features" },
        { "type": "fix", "section": "Bug Fixes" },
        { "type": "hotfix", "section": "Bug Fixes" },
        { "type": "perf", "section": "Performance Improvements" },
        { "type": "revert", "section": "Reverts" },
        { "type": "docs", "section": "Documentation", "hidden": false },
        { "type": "style", "section": "Styles", "hidden": true },
        { "type": "chore", "section": "Miscellaneous Chores", "hidden": false },
        { "type": "refactor", "section": "Refactoring", "hidden": false },
        { "type": "rework", "section": "Refactoring", "hidden": false },
        { "type": "test", "section": "Tests", "hidden": true },
        { "type": "build", "section": "Build System", "hidden": true },
        { "type": "ci", "section": "Continuous Integration", "hidden": true }
      ]
    }
  },
  "writerOpts": {
    "reverse": true,
    "commitsSort": ["scope", "subject", "committerDate"]
  },
  "parserOpts": {
    "headerPattern": "(?:\\(Merged PR \\d+: \\))?([a-zA-Z]+)(?:\\(([\\w$\\.\\-*\\s\\,]*)\\))?\\!?\\s?[\\:\\-](.*)",
    "headerCorrespondence": ["type", "scope", "subject"]
  }
}

changelog.context.json

{
  "commit": "commit",
  "host": "*********",
  "owner": "*********",
  "repository": "*********",
  "version": "x.y.z"
}

GoMino avatar Aug 10 '22 10:08 GoMino

Can we add support for bitbucket ? In bitbucket also when we try to merge PR it add this message as default. Merged in feature/DM-175-tag-management (pull request #156)

as19ish avatar Oct 18 '22 14:10 as19ish

Seeing as standard-version is no longer supported I was able to implement a solution using the Regex from @GoMino and absolute-version/commit-and-tag-version.

Here's the .versionrc configuration I'm using:

{
  "writerOpts": {
    "reverse": true,
    "commitsSort": false
  },
  "parserOpts": {
    "headerPattern": "(?:\ \(Merged PR \\d+: \\))? ([a-zA-Z]+) (?:\ \(([\\w$\\.\\-*\\s\\,]*)\\))?\\!? \\s? [\\:\\-](.*)"
  },
  "header": "# Changelog\n\nThis document maintains a list of released versions and changes introduced by them.\nThis project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html)\n",
  "releaseCommitMessageFormat": "chore(release): {{currentTag}} [skip ci]",
  "types": [
    {
      "type": "feat",
      "section": "Features",
      "hidden": false
    },
    {
      "type": "fix",
      "section": "Bug Fixes",
      "hidden": false
    },
    {
      "type": "perf",
      "section": "Performance Improvements",
      "hidden": false
    },
    {
      "type": "refactor",
      "section": "Code Refactoring",
      "hidden": false
    },
    {
      "type": "style",
      "section": "Coding Conventions",
      "hidden": true
    },
    {
      "type": "build",
      "section": "Build System",
      "hidden": false
    },
    {
      "type": "test",
      "section": "Automated Tests",
      "hidden": false
    },
    {
      "type": "ci",
      "section": "CI/CD Workflows",
      "hidden": false
    },
    {
      "type": "docs",
      "section": "Documentation",
      "hidden": false
    },
    {
      "type": "chore",
      "section": "Miscellaneous",
      "hidden": true
    }
  ],
  "skip": {
    "bump": false,
    "changelog": false,
    "commit": false,
    "tag": false
  },
  "tagPrefix": "v",
  "noVerify": true,
  "commitAll": true
}

This can be run using:

npx commit-and-tag-version --dry-run

mholttech avatar Jun 12 '23 17:06 mholttech

@mholttech I've also implemented similar however it seems to break the semantic version bumping. eg: feat: commits no longer bump a minor version, only a patch. Have you noticed the same?

"headerPattern": "(?:\\(Merged PR \\d+: \\))?([a-zA-Z]+)(?:\\(([\\w$\\.\\-*\\s]*)\\))?\\!?:(.*)"

KadinHoneyfield avatar Jul 26 '23 00:07 KadinHoneyfield

yes we observed the same. It looks like that the config is not propagated to the bumper and is still uses the default without the optional "Merged PR ...". The patch update then is the default when bumping and not finding a feat.

jan-mrm avatar Jul 26 '23 06:07 jan-mrm

That's my findings aswell, looks like #821 was raised for it here. Just need to raise it on absolute-version/commit-and-tag-version instead.

KadinHoneyfield avatar Jul 27 '23 00:07 KadinHoneyfield

In addition to the version bumping issue mentioned above, commits using the breaking changes syntax (type!: subject) will not receive a major version increase unless you also include the following in your "parserOpts" config:

"breakingHeaderPattern": "(?:\\(Merged PR \\d+: \\))?([a-zA-Z]+)(?:\\(([\\w$\\.\\-*\\s]*)\\))?\\!?!:(.*)"

chunick avatar Aug 07 '23 18:08 chunick

I´m having the same issue but using the cz-conventional-changelog package with lerna and NX do you know if this fix works for both?

elassol avatar Sep 11 '23 14:09 elassol