-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add an option to output the version that would be published #753
Comments
I think you can run a custom script in the At this point the version in package.json is set. Your custom script can read it and write it into your build files |
I would but unfortunately I don't publish with npm. My build script is executed way before the semantic release. |
you can use semantic-release without publishing to npm, you can create a prepare plugin at which point the new version will be available to your script, see for example https://github.com/GabrielDuarteM/semantic-release-chrome/blob/dd75ea42bdc6a21a138ae76fc73dd13b2570d43d/src/prepare.ts#L22 see also https://semantic-release.gitbooks.io/semantic-release/docs/extending/plugins-list.html |
You can also use the @semantic-release/exec to run a script at any step you'd like that can be passed the new version number. Something like that: {
"release": {
"prepare": [
"@semantic-release/npm",
{
"path": "@semantic-release/exec",
"cmd": "my-script ${nextRelease.version}",
},
],
}
} With this config the npm plugin is going to update your |
The problem with all these solutions is that I need to have two configurations : One that outputs the version or sets it somewhere, and one for the actual release in gitlab (tag, etc.) which doesn't seem to be possible easily. For now I think i'll parse the output of a dry-run, but this is really brittle if the output changes. |
Do you mean two semantic-release config? Can you clarify why would you need two configs? |
I will try to be more detailed about my workflow. I have a Gitlab-CI pipeline that does this jobs in order :
The problem is that the customer wants to see the version number inside the application (and maybe the changelog later). Wich means I need the version number during step 1, but I don't want to release yet (the tests could still fail). The two semantic-release configurations would allow me to use
But the preferred method would just be to have a command that outputs the next version. I would use that during step one. I hope it's more clear, don't hesitate to ask for more details. |
Thanks for the clarification. semantic-release is build around the following ideas:
It seems your steps 1 and 2 are actually tests, but handled like a release. In semantic-release, it has to be either a test step or a release step. If it's a test, there is no version determined, if it's a release there is one. If you need the version number for step 1 and 2 then it's a release. Your workflow could be viewed as doing two different release:
We usually handle this case via npm dist-tag. Until #563 get implemented the support of dist-tag is fairly simple unfortunately as we support one dist-tag config in the Once #563 is implemented you could do the following workflow:
This way:
With the current implementation you can do something that involve some manual steps:
|
I can't use this workflow unfortunately. My project is not a NPM library and it's not released on any NPM registry. My real artifact is a docker image. Moreover, the entire release process can't be executed in one go because of infrastructure constraints: some steps (deploying the review app for example) must be executed in a particular context to be able to deploy to kubernetes, the deploy part must be in a single gitlab job so I can re-deploy or rollback with gitlab's features, etc. I understand this may not really be the use case this library is intending to solve, so if you think it's outside the scope, I would understand and you can feel free to close this issue (I'll be able to hack something and solve my problem). I still think it could be useful to have some way to configure the script's output to make it easier to parse when doing a dry run (Doing a dry run is the way to solve my use case as mentionned in the faq by the way). for example
or something like that (my example is ugly, only to illustrate) |
In most cases where such feature was requested there was a better solution to implement the desired workflow, so it hasn't been implemented so far. It seems the workflow explained here is very specific and uncommon. However we might consider adding such feature if there is other workflow that would require it. So if anyone using a workflow that would benefit from that feature, please add a comment to this issue to explain your workflow with as much detail as possible. |
I'm not sure I completely agree with that statement. In previous versions this was sometimes hacked together using
Obviously not an ideal solution. So I'm happy to see there's FAQ now and some other approaches as mentioned in the first few responses above. @BenoitAverty imho if you're not using this product for NPM please consider looking for a less opinionated product, many of which have been mentioned in older issues related to version numbers. |
I agree with @pvdlg, we can leave the issue open for some more time to see if others have a similar workflow, but I can’t recall anyone form the past |
@jhabdas I tried other libs but semantic-release is the only one that is this high-level. I thought it would be less work to implement the compte workflow (parse commits, determine version bump, generate changelog, release) by configuring semantic-release that by redoing the same work with, for example, conventional-changelog. I still think it was easier, but maybe it's less elegant because it's a lot of configuration. |
the feature would be extremely useful for me as well. I need the next version printed in several places and run scripts with this value. |
@andresmijares could you explain your workflow and why such feature would be useful to you? |
Sure thing, I'm using the package to manage release for another project in a different language, this is going to build the proyect and publish in our artifact repository name as the version, which mean that in order to build the distribution I need to pass the version number. I've tried to create a script that takes this version number and make something like: "release": {
"prepare": [{
"path": "@semantic-release/exec",
"cmd": "./build.sh --release -v ${version}"
}]
} which I thought it would work but I havent had any luck with it. |
Can you clarify what "I havent had any luck with it" means? |
btw, as indicated in semantic-release/exec#usage the proper syntax is "release": {
"prepare": [{
"path": "@semantic-release/exec",
"cmd": "./build.sh --release -v ${nextRelease.version}"
}]
} |
my bad, I just figured I had 1 issue not related to the package, it worked like charm, I decided to use Thank you for the comment! |
@BenoitAverty I do something like you, and end up just using a bit of sed/awk magic to cat the next version (if there is one) to a We have an npm library, that is consumed by some app, which is deployed to a review environment if on a feature branch. This allows us to publish the npm package under package_name@next when developing against a feature |
Just wanted to drop my vote for this feature as well. I have a couple of restrictions on my workflow that prevent me from using semantic-release fully without this feature.
The workflow I was thinking is as follows:
I've run into two problems with this:
This is the setup I have thus far: 'use strict';
module.exports = {
verifyConditions: [],
analyzeCommits: ['@semantic-release/commit-analyzer'],
verifyRelease: [
{
path: '@semantic-release/exec',
cmd: 'echo ${nextRelease.version} > .version',
},
],
generateNotes: [],
prepare: [],
publish: [],
success: [],
fail: [],
}; # compute the version from the commit message
npx semantic-release --dry-run --branch "$( git rev-parse --abbrev-ref HEAD )" --no ci
# update package.json & package-lock.json
## note: the subshell is needed because you can't read and write to the same file
echo "$(jq ".version = \"$( cat .version )\"" package.json )" > package.json
echo "$(jq ".version = \"$( cat .version )\"" package-lock.json )" > package-lock.json
git add package.json package-lock.json
# disable post-commit hook temporarily, otherwise ammending the commit will execute this again
[ -x "$hook" ] && chmod -x "$hook"
git commit --amend --allow-empty
chmod +x "$hook" I could get around the limitation by using Ideally I would run I will say that this breaks most of the assumptions that Another idea would be to implement this via a plugin of some sort, but the checking of various git states is actually in the main semantic-release code rather than a plugin which can be disabled. |
I also stumbled across semantic-release because I really like the idea of having version numbers detached from human emotions. However in our case we are building a Unity application and need to build both an android and an ios binary out of it. So our complete process is something like:
Unfortunately this cannot all be done on the same machine let alone in one process. Especially building iOS apps requires a macOS machine while the Unity Build takes place in a Kubernetes cluster. The build number also needs to be set before the build process starts. I totally understand that the initial use case for semantic-release is basically releasing an npm package and the language of semantic-release is identical to the package system being used. There are a lot of cases where this luxury doesn't exist. Having to hack around instead of just having a simple option that prints the expected version is a bit sad. Even if semantic-release is opinionated it appears to be in widespread enough use that you might consider all the people that don't use it for npm packages but have build systems that semantic-release simply doesn't support or have a multistage pipeline in their CI system that requires the version before a final release. |
I also have a workflow use case using next.js and the nx monorepo tool. In next.js it is easy to add an app version at build time using the For example: module.exports = withNx({
generateBuildId: async () => {
const pkgVersion = JSON.parse(readFileSync(`${__dirname}/../package.json`).toString()).version
return semver.parse(pkgVersion).version
},
webpack: (config, { buildId }) => {
config.plugins.push(
new webpack.DefinePlugin({
'process.env.APP_VERSION': buildId
})
);
return config;
},
}); And then, in say, a gitlab pipeline file, I usually would run the following:
The problem is, the build can still fail at exporting and generating the static files. But then I will have already added the tag to the repository. What I would like to do is write to Edit: Using @xesf approach, I'm able to workaround this like this: plugins:
[
'@semantic-release/commit-analyzer',
'@semantic-release/release-notes-generator',
'@semantic-release/changelog',
[ '@semantic-release/npm', { npmPublish: false } ],
[
'@semantic-release/exec',
{
prepareCmd: 'yarn nx affected --target=export --base=$AFFECTED_BASE --parallel',
},
],
[
'@semantic-release/git',
{
assets: [ 'package.json', 'CHANGELOG.md' ],
message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
},
],
'@semantic-release/gitlab',
] |
@srosato you can check out my approach here https://semantic-release-plus.gitbook.io/semantic-release-plus/recipes/utility/expected-next-version You will have to use the semantic-release-plus fork of semantic-release - https://www.npmjs.com/package/semantic-release-plus. Notice the This may also interest you - https://semantic-release-plus.gitbook.io/semantic-release-plus/recipes/monorepos/nx-monorepo |
Hi,
What I really need is to execute the plugins independently, on different stages:
Is there any chance that semantic-release allows for independent execution of the configured plugins? |
Yes it does (kinda). Basically use --dry-run. We have the following step: semantic-versioning:
stage: determine-version
image: node:latest
script:
- npm i
- npx semantic-release --dry-run
- test -f version.env
artifacts:
reports:
dotenv: version.env With this .releaserc.yaml plugins:
- "@semantic-release/commit-analyzer"
- "@semantic-release/release-notes-generator"
- [ "@semantic-release/changelog",
{
"changelogFile": "CHANGELOG.md"
} ]
- - "@semantic-release/exec"
- verifyReleaseCmd: "./.release-utils/verifyRelease.sh ${nextRelease.version}"
- - "@semantic-release/gitlab"
- gitlabUrl: https://redacted
- - "@semantic-release/git"
- assets: [ "CHANGELOG.md", "package.json" ]
message: "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}" and this script: echo "NEXT_VERSION=$1" > version.env I have tried to get it to work with directly passing an echo command to semantic release but that didn't work due to shell issues. |
I hit this issue as well. It surprises me that it is so requested and that it was integrated in a fork, but it can't make it into the main distribution. |
@DanySK which fork? |
To be specific this recipe https://github.com/semantic-release-plus/semantic-release/blob/master/docs/recipes/expected-next-version.md |
Chiming in the conversation to bring up another way to achieve the result described in the subject. This solution uses Github workflow specific commands, namely the example-defining-outputs-for-a-job.
...
["@semantic-release/exec",
{
"publishCmd": "echo ::set-output name=nextVer::${nextRelease.version}"
}
]
...
- name: run semantic release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx semantic-release
id: ver
outputs:
output1: ${{ steps.ver.outputs.nextVer }}
print:
needs: release
runs-on: ubuntu-20.04
steps:
- name: print version
run: echo ${{ needs.release.outputs.output1}} Full running exampleSemantic Release configuration file: https://github.com/maxiride/semantic-release-test/blob/4d330f2d46408f2019c33661f7f67f3e836f7bd1/.releaserc.json Example run: https://github.com/maxiride/semantic-release-test/actions/runs/1755300704 This method is pretty hacky but gets the job done. Nonetheless a semantic release built-in method would be more future proof to use. An official Github Action with proper inputs and outputs would be even more appreciated. |
This is a very nice strategy, too. The differences with the force-push approach are that:
|
Much easier like suggested earlier:
Still, waiting for a proper solution! |
@maxiride Have you worked out a way to do this in a pull request? I keep running into a problem where it does not recognize the PR as being one of the approved branches, even if I do
|
thanks for everyone that showed how to get the version parsed, or created a fork, or created a one liner. This was very helpful. Thanks also for the original developers of the tool! You did an amazing job! It would just be more amazing if you incorporated this massive feedback of adding this simple functionality |
Not official, but an action that makes the next version available as a step output on Github Actions is here – |
An issue that is 5 years old and we still don't have an official way of outputting the value. |
I solved it for my et project by writing own local semantic-release plugin. for example // <project-root>/release-exec.js
import { writeFileSync } from "fs";
const verifyRelease = async (_, context) => {
const next = context.nextRelease.version;
// do whatever you want with this new version. let's say we save it into .VERSION file
writeFileSync(".VERSION", next);
};
export default {
verifyRelease,
}; And then in the semantic-release config file // <project-root>/release.config.js
export default {
plugins: [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/github",
"./release-exec.js",
],
}; |
Adding my vote here as well. It's a pretty common use case to show the version number and possibly the change log in the app, that must be created before the build. |
I am using this plugin to update the version number in a file in the repo: https://github.com/jpoehnelt/semantic-release-replace-plugin |
Scenario: If one of the app/lib fails, we don't want to bump the mono-repo version, and it is easy to remove/invalidate the artifact file. So if along with --dry --no-ci which we are grateful for, can we get a |
For me, what's important is that I ship artifacts and not source code. If a certain build is approved by QA, vetted by security etc, then it is THAT build that should be released. A build of the same source code is not the same. Because of all the systems that we work with reproducible builds aren't a thing yet. We tag the artifact with all the checksums of the tools used, and they might differ if we choose to release a 3 day old build. Rebuilding them just for the sake of releasing introduces unnecessary risk. So when we build something, we pre-calculate the version number and add it in the binary. When we then choose to release a certain tag we do not need to rebuild the binary. It is tagged with a commit and a version number. And we get to tell our customers that the binary they're getting is the same the one we tested throughout all our environments. |
@kristof-mattei I have the following workflow based on “trunk based development” on a monorepo that has many web apps and libs. Workflow
This is not a core engine or some complex application - its mostly a bunch of high performing static websites that rely on shared libraries. Here I also don't want to just semantic upgrade only for release/*app branches. I need to be able to leverage main as a source of tracking. I'm open to feedback if you think I can use semantic release any other way. Currently I'm scraping semantic release dry run output. A machine readable json seems to be lesswrong than having none. |
You can use this plugin that sets GitHub Action output variables to be consumed in later steps or jobs. |
Feature request
New feature motivation
I am currently implementing automatic releases for my project, which is a web application. The project currently satisfies my needs as I can disable the npm plugins and replace it with gitlab plugins.
The problem is that I need to put the version of my project into the built application (via Webpack's DefinePlugin), but the version field of my package.json is always set to 0.0.0.
I would like to be able to use semantic-release to print the version that would be published and use it in webpack DefinePlugin.
Currently, the only way to do that would be to parse the output of a dry-run, but it is complicated and not stable.
New feature description
I see two ways this could happen :
semantic-release --print-next-version
I could open a PR for the first solution if you'd like. The second one is a bigger task (probably several tasks)
The text was updated successfully, but these errors were encountered: