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

Detect if release is necessary, exit if not #192

Open
enriquecaballero opened this issue Jun 7, 2017 · 12 comments · May be fixed by #750
Open

Detect if release is necessary, exit if not #192

enriquecaballero opened this issue Jun 7, 2017 · 12 comments · May be fixed by #750

Comments

@enriquecaballero
Copy link

semantic-release has a sweet way of detecting whether or not it should follow through with a release. Some commits are just docs, style, and even refactor, that don't really affect the published build, hence a release shouldn't really take place. Currently, standard-version tags the release regardless of what the commits are -- for commits that don't affect the build, standard-version bumps the version number as a patch. We use standard-version at work for our CI builds and it works great for publishing to our internal registry, but it overpopulates our registry with unnecessary releases. The same with Bitbucket and unnecessary release tags.

Is this a viable feature that can be implemented into standard-version? Or is always releasing the correct behavior and should always be expected?

@tunnckoCore
Copy link

@enriquecaballero sounds like good idea, i like it too.

Btw are you saying that you integrated the standard-version in the CI? What CI you use? Travis, Circle? I'm just thinking how can set it on CI, so i won't need to do it manually, but just like every needed commit (like in SR).

@xml
Copy link

xml commented Nov 12, 2017

I just tested this, and confirmed that standard-version will create a release even if there are no new commits at all. Even if the immediate previous commit is in fact just the last release from `standard-version, it will create a new one, with a patch-level version bump.

@stevemao
Copy link
Member

tldr
If you do npm version it will also create a release even if there are no new commits at all. Reasons including you might messed up with your preview release or docs changes etc. And this is supposed to be a better npm version

@bcoe
Copy link
Member

bcoe commented Nov 29, 2017

@stevemao I could see an argument for having a --force option, that creates a release even if there's no changes in the history (which is something I sometimes do). Perhaps the default behavior could be to warn and exit though? (with a tip as to how to use --force).

@enriquecaballero what do you think? (also sorry for this incredibly slow reply).

@stevemao
Copy link
Member

Sounds good.
Side: do you think that npm and yarn should behave the same?

@rodoabad
Copy link

rodoabad commented Jun 1, 2018

Is this going to be a feature in the future? This is handy for CI especially when your CI pushes tags and commits back to Git. This will cause an endless cycle as each push will trigger a new version that's going to push a new change log again and so on.

@vicrep
Copy link
Contributor

vicrep commented Jan 15, 2019

Jumping in on this, it'd be really nice if standard-version supported this.

In the meantime, if you're stuck on this, I wrote/use a small naive bash script to perform this type of check on CircleCI:

#!/bin/bash

set -e

{
  git describe --tags --exact-match > /dev/null 2>&1 && {
    echo "Release is already associated to a tag. Skipping..."
    exit 0
  }
} || {
  echo "Running new release"
  npm run release && {
    git push origin $CIRCLE_BRANCH && git push origin --tags
  } || {
    echo "Release aborted as branch was updated during build."
  }
}

exit 0

Where npm run release calls standard version, and an assumption is made that all git tags are generated by standard-version.

should be easily portable to other CI providers (only specific part is$CIRCLE_BRANCH)

@Mike-Neto
Copy link

I'm going to take a look into getting this done this week 👍

@alanivey
Copy link

alanivey commented Apr 7, 2020

In case it helps someone, here's what I have in my CI script. In commits since the previous tag, it'll proceed if any commit subject matches ^(feat|fix|perf|refactor|revert): or !:, or if the body contains BREAKING CHANGE:. Improvements or suggestions welcomed!

if \
  { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -i -E '^feat|fix|perf|refactor|revert$' ; } || \
  { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%s' | cut -d: -f1 | sort -u | sed -e 's/([^)]*)//' | grep -q -E '\!$' ; } || \
  { git log "$( git describe --tags --abbrev=0 )..HEAD" --format='%b' | grep -q -E '^BREAKING CHANGE:' ; }
then
  npx --quiet standard-version@7.1.0
else
  echo "No applicable changes since the previous tag, skipping..."
fi

@derekgreer
Copy link

+1

@ianstormtaylor
Copy link

@bcoe any follow up on this? Could this change be made?

I'm looking in to using standard-version for Slate, but people are often contributing small docs fixes which would result in tons of no-op patch releases going out which would be very frustrating.

@darkobits
Copy link

darkobits commented Mar 30, 2021

Here's a proposal for a possible solution that wouldn't involve file blacklists etc:

Use Presets

This might actually solve two issues with standard-version at the moment:

  1. If you run standard-version twice, back to back, without any commits in between, the second run will still generate a new tagged commit and update the change log. Maybe there is some edge case where this is desirable, but it does seem a little silly.
  2. We run standard-version blindly in CI, and one or more commits have been made since the last tagged release commit, but they may not deem a new release necessary. (ie: this issue)

In both cases, the solution seems to be to make standard-version smart enough to know when to generate a release commit and when it should no-op.

One way this could be achieved while not imposing any particular, strict process on users is via presets. At the moment, presets are used primarily to translate various commit types into the headings they will appear under in a project's CHANGELOG.md, but also support many of the standard-version CLI options. standard-version uses this one by default. The full spec can be found here.

The definition for the types option reads:

An array of type objects representing the explicitly supported commit message types, and whether they should show up in generated CHANGELOGs.

And a typical value for types looks like this:

"types": [
    {"type": "feat", "section": "Features"},
    {"type": "fix", "section": "Bug Fixes"},
    {"type": "chore", "hidden": true},
    {"type": "docs", "hidden": true},
    {"type": "style", "hidden": true},
    {"type": "refactor", "hidden": true},
    {"type": "perf", "hidden": true},
    {"type": "test", "hidden": true}
]

So, what if standard-version only considers the registered commit types in whatever preset its using to determine if a release should take place?

It already does something like this when determining what type of release to create, the difference I'm proposing is that if it finds (1) no commits at all or (2) no commits that match one of the "explicitly supported commit message types", it exits without creating a release.

This proposal still maintains the usefulness of the hidden option, which indicates a supported commit type that should trigger a release, but will not appear in CHANGELOG.md.

Omitting a commit type from types entirely would then indicate that not only should commits of that type not appear in the change log, but that they should not even be considered as candidates when determining if a release is necessary.

This would also allow users to continue following the same commit message format (conventional, for example) and run tools like commitlint, they would just need to decide on one or more commit types to use for commits that should not trigger a release. Working within the current implementation of the default preset, a commit type like misc could be used to bypass releasing.


Addendum:

  • I would also suggest dropping docs as a registered commit type since, as @ianstormtaylor pointed out, such commits should almost never result in the creation of a release.
  • Additionally, a --force option could be added to give users the behavior we have today, where a new release commit is always created when standard-version is invoked, regardless of the commit history since the last release commit.

nelsonfncosta added a commit to nelsonfncosta/standard-version that referenced this issue Apr 23, 2021
@nelsonfncosta nelsonfncosta linked a pull request Apr 23, 2021 that will close this issue
nelsonfncosta added a commit to nelsonfncosta/standard-version that referenced this issue Apr 23, 2021
nelsonfncosta added a commit to nelsonfncosta/standard-version that referenced this issue Apr 23, 2021
nelsonfncosta added a commit to nelsonfncosta/standard-version that referenced this issue Apr 23, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging a pull request may close this issue.