Standard-version: Can I create a release in addition to a simple tag?

Created on 8 Jul 2020  Â·  2Comments  Â·  Source: conventional-changelog/standard-version

I was hoping with this I could actually create a git release using the changelog as the body, but it wasn't obvious if I could do that exactly.

Is it supported? How would one do it?

Most helpful comment

The way I do it is slightly different from what @stroym suggested. Instead of parsing the output of standard-version --dry-run, which is indeed hacky-ish, I let it run normally and skip the commit step. It works more or less like this:

  1. Clone your repository and checkout to the target commit of the release. This step is not strictly necessary, but it's usually the default procedure for continuous integration systems.
  2. Next, tag the commit to be released and generate the changelog (release body). You can do this through the command standard-version -i RELEASE_BODY.md --skip.commit [other options]. Here, you may also add other configuration that you deem necessary (e.g. formatting of the changelog).
  3. Then, publish the newly created tag. It's as simple as calling git push --follow-tags.
  4. Lastly, create the release based on the published tag and the generated changelog.

To demonstrate how it all fits together, here's a simple GitHub Actions workflow configuration:

name: release
on: push
  branches: [release-*]
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0 # gives standard-version access to all previous commits
      - name: generate tag and release body
        run: |
          git config user.name example
          git config user.email [email protected]
          npx standard-version -i RELEASE_BODY.md --skip.commit
      - name: publish tag
        id: publish_tag
        run: |
          git push --follow-tags
          echo ::set-output name=tag_name::$(git describe HEAD --abbrev=0)
      - name: create release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          release_name: Release ${{ steps.publish_tag.outputs.tag_name }}
          tag_name: ${{ steps.publish_tag.outputs.tag_name }}
          body_path: RELEASE_BODY.md

All 2 comments

I don't think there's a straightforward way of doing that.
I'm not entirely sure what you mean by "git releases", so I'm going to assume you mean a GitHub (or your preferred platform) release. If you just want to add the changelog text to your tag, most of this still applies.
All in all it shouldn't be too hard to accomplish, though it would get a bit hacky. I'm going to lay out how I would do it and then elaborate on that:

  1. Get the current changelog message;
  2. make standard-version release;
  3. make GitHub (or your preferred platform) release.

You'd probably have to use something like standard-version --dry-run >> file.txt (you could --skip.tag --skip.commit --skip.bump but that doesn't really help in this case) to generate the current changes, but the output of that looks something like this:

✔ bumping version in <bumpfile> from A.B.C to X.Y.Z
✔ outputting changes to CHANGELOG.md

---
<text that woul be added to the changelog body>
---

✔ committing CHANGELOG.md
✔ tagging release vX.Y.Z
ℹ Run `git push --follow-tags origin <branch>` to publish

As you can see there's a bunch of text that you don't want, so you'd have to parse the file contents between the two sets of ---. (You could do it in a oneliner together with sed or your preferred way to parse in bash to avoid redirrecting the output to a file that you would then have to delete.)
With that you have the text that should be go to the release notes.

After that you run standard-version as usual to actually generate the changelog and the other things.

Then you need to get the latest tag, which git describe HEAD --abbrev=0 will do for you. (In case you just want the tag to have a custom message, you'd need to use --skip.tag and create it yourself via git tag -m "text", or amend the one standard-version creates for you.)

After that you'd need to use cURL (or something similar) to create a release via REST API. Assuming GitHub, check this.

You might be able to do all of this by supplying custom lifecycle scripts to the various stages (such as "postchangelog") standard-version goes through, which would be a nicer way of doing that, but it might be too much of a pain to do.

The way I do it is slightly different from what @stroym suggested. Instead of parsing the output of standard-version --dry-run, which is indeed hacky-ish, I let it run normally and skip the commit step. It works more or less like this:

  1. Clone your repository and checkout to the target commit of the release. This step is not strictly necessary, but it's usually the default procedure for continuous integration systems.
  2. Next, tag the commit to be released and generate the changelog (release body). You can do this through the command standard-version -i RELEASE_BODY.md --skip.commit [other options]. Here, you may also add other configuration that you deem necessary (e.g. formatting of the changelog).
  3. Then, publish the newly created tag. It's as simple as calling git push --follow-tags.
  4. Lastly, create the release based on the published tag and the generated changelog.

To demonstrate how it all fits together, here's a simple GitHub Actions workflow configuration:

name: release
on: push
  branches: [release-*]
jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v2
        with:
          fetch-depth: 0 # gives standard-version access to all previous commits
      - name: generate tag and release body
        run: |
          git config user.name example
          git config user.email [email protected]
          npx standard-version -i RELEASE_BODY.md --skip.commit
      - name: publish tag
        id: publish_tag
        run: |
          git push --follow-tags
          echo ::set-output name=tag_name::$(git describe HEAD --abbrev=0)
      - name: create release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          release_name: Release ${{ steps.publish_tag.outputs.tag_name }}
          tag_name: ${{ steps.publish_tag.outputs.tag_name }}
          body_path: RELEASE_BODY.md
Was this page helpful?
0 / 5 - 0 ratings

Related issues

roboto84 picture roboto84  Â·  3Comments

marcoturi picture marcoturi  Â·  5Comments

SteveVanOpstal picture SteveVanOpstal  Â·  4Comments

noreiller picture noreiller  Â·  5Comments

denouche picture denouche  Â·  6Comments