-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat: add optional annotated or signed tags #1871
base: master
Are you sure you want to change the base?
feat: add optional annotated or signed tags #1871
Conversation
Hi, may I ask what's the status of this PR? We are also missing this feature, and adding it will be highly appreciated 🙏 |
sorry for not getting back to it. Both @travi and I are too occupied right now, but we are discussing how to make more time for @semantic-release. Please give us some more time |
tools like miniver currently require annotated tags https://github.com/jbweston/miniver
|
I need annotated tags as well |
Meanwhile, I concocted a terrible workaround to be able to get annotated tags: tagFormat: "${version}"
plugins:
- "@semantic-release/commit-analyzer"
- "@semantic-release/release-notes-generator"
- "@semantic-release/changelog"
-
- "@semantic-release/exec"
- publishCmd: |
git tag -a -f ${nextRelease.version} ${nextRelease.version} -F CHANGELOG.md
git push --force origin ${nextRelease.version}
# commands that need an annotated tag to work
- "@semantic-release/github"
- "@semantic-release/git" |
As a alternative to @DanySK...
diff --git a/node_modules/semantic-release/lib/git.js b/node_modules/semantic-release/lib/git.js
index 8aaf884..53a610f 100644
--- a/node_modules/semantic-release/lib/git.js
+++ b/node_modules/semantic-release/lib/git.js
@@ -221,7 +221,7 @@ async function verifyAuth(repositoryUrl, branch, execaOptions) {
* @throws {Error} if the tag creation failed.
*/
async function tag(tagName, ref, execaOptions) {
- await execa('git', ['tag', tagName, ref], execaOptions);
+ await execa('git', ['tag', tagName, ref, '-s', '-m', `release ${tagName}`], execaOptions);
}
/** |
Still, it would be nice to see your PR merged |
@DanySK - While you wait, I recommend you check out https://github.com/abstracter-io/atomic-release You can create a custom command that creates an annotated tag instead of a lightweight |
Hello, what is the status of this PR? |
I'm also interested to understand what is holding this back, it's a major hassle for me at the moment |
We ran into an issue that looked like this, but in the end turned out to be something slightly different. Semantic-release creates notes and Gitlab treats those the same as commits. Thus when requiring signed commits, they also require you to sign notes, which is not possible. |
Would like to see this as well! |
@travi Is there anything one can do to help with the progress of this PR? I would like to enable signed commits and tags for my repository but cannot do that due to the fact that this feature is missing with this project. My GPG key for the project would be available as a secret in GitHub Actions and Git would obviously be configured to use the mentioned key. |
Looking forward to having this merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a few comments. The main doubt I have with this change is the git config precedence over the semantic-release
one.
I also notice you haven't added test cases covering your changes.
P.S. Sorry for the late response, I do realize this PR is over 2 years old, and I hope you're still willing to push it through after all that time.
await execa("git", ["tag", tagName, ref], execaOptions); | ||
async function tag(tagName, ref, {tagAnnotate, tagSign, tagMessage}, execaOptions) { | ||
const args = ["tag", tagName, ref]; | ||
const gitTagSign = await shouldSignTag(execaOptions); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the reasoning behind accounting for & giving precedence to the git configuration?
I see a few problems with that:
- if I set
tagSign
tofalse
in my config, it might still sign the tag based on my system configuration - it makes the changes breaking, as it will start unsolicitedly signing tags
Because of that, I don't think the git configuration should be accounted for. If overriding the release configuration behavior is needed in a specific setup, overriding it with the CLI flag is enough.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I remember correctly...
I check for the git config first because signed tags must have a message, otherwise it fails. Currently if I set tag.gpgsign
to true
it will fail when creating a tag.
So if you set tagSign
to false
and tag.gpgsign
is true
it will still sign a tag to prevent the release from failing.
That said I don't think it is unsolicitedly if I previously set tag.gpgsign
.
Does this make sense?
If one of -a, -s, or -u is passed, the command creates a tag object, and requires a tag message.
@@ -296,7 +320,9 @@ test.serial('Read configuration from file path in "extends"', async (t) => { | |||
branches: ["test_branch"], | |||
repositoryUrl: "https://host.null/owner/module.git", | |||
tagFormat: `v\${version}`, | |||
plugins: ["plugin-1", ["plugin-2", { plugin2Opt: "value" }]], |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably not be removed.
Default: `release ${nextRelease.version}`<br> | ||
CLI arguments: `-tm`, `--tag-message` | ||
|
||
The message for the tag. The tag message is generated with [Lodash template](https://lodash.com/docs#template) and will be compiled with the `nextRelease` variable. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nextRelease
being an internal variable, there should be a link to its documentation.
@@ -23,6 +23,14 @@ Usage: | |||
.option("b", { alias: "branches", describe: "Git branches to release from", ...stringList, group: "Options" }) | |||
.option("r", { alias: "repository-url", describe: "Git repository URL", type: "string", group: "Options" }) | |||
.option("t", { alias: "tag-format", describe: "Git tag format", type: "string", group: "Options" }) | |||
.option("ta", { | |||
alias: "tag-annotate", | |||
describe: "Whether to make an unsigned, annotated tag", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Streamline to "Toggle tag annotation".
type: "boolean", | ||
group: "Options", | ||
}) | ||
.option("ts", {alias: "tag-sign", describe: "Whether to make GPG-signed tag", type: "boolean", group: "Options"}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Streamline to "Toggle tag signing".
{ | ||
tagAnnotate: options.tagAnnotate, | ||
tagSign: options.tagSign, | ||
tagMessage: template(options.tagMessage)({ nextRelease }), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would make the tagMessage
optional, and default to the nextRelease.gitTag
.
Example use case: I want my release tags to be signed, but I don't care about the annotation message.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tought it already was optional, and the default, set on get-config.js
, is release \${nextRelease.version}
.
Looking forward to this getting merged. |
In the meantime, my workaround doesn't require a force push for using Gitlab API. #!/usr/bin/env bash
# release.sh
# TODO: remove when merged, this is workaround for annotated tags
# https://github.com/semantic-release/semantic-release/pull/1871
if [ -z "$1" ]; then
echo "Please provide a tag."
echo "Usage: ./release.sh v[X.Y.Z]"
exit
fi
GIT_TAG=$1
JSON_STRING=$( jq -n \
--arg tag_name "${GIT_TAG}" \
--arg ref "main" \
'{tag_name: $tag_name, ref: $ref}' )
if [ -n "$2" ]; then
NOTES=$2
JSON_STRING=$(echo $JSON_STRING | jq -r --arg message "${NOTES}" '.message = $message')
fi
echo "Recreating annotated tag ${GIT_TAG}..."
URL="https://gitlab.com/api/v4/projects/${CI_PROJECT_ID}/repository/tags"
curl -X DELETE "${URL}/${GIT_TAG}" -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}"
curl -X POST "${URL}" -H "Content-Type: application/json" -H "PRIVATE-TOKEN: ${GITLAB_TOKEN}" -d "${JSON_STRING}"
{
...
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/git",
[
"@semantic-release/exec",
{
"publishCmd": "./release.sh ${nextRelease.gitTag} \"${nextRelease.notes}\""
}
],
"@semantic-release/gitlab"
],
...
} |
I'm eagerly awaiting the merge of this improvement 🤞 |
This adds the option to annotate or sign the tag.
This is opt-in, the default values will result in the current implementation.
To make an unsigned, annotated tag:
To make an signed tag:
Or by setting the git config
tag.gpgsign
to true.To customize the tag message:
The message will be applied to the tag only if one of the following is
true
:tagAnnotate
,tagSign
or git configtag.gpgsign
. Otherwise the tag is considered lightweight, which is the current implementation.Also,
tagSign
takes precedence overtagAnnotate
. The git configtag.gpgsign
takes precedence over both.