Skip to content

Commit 9773e85

Browse files
authored
add an option to create annotated tags (#22)
2 parents 756546d + 7f962ee commit 9773e85

File tree

10 files changed

+182
-9
lines changed

10 files changed

+182
-9
lines changed

Diff for: CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

77
## [Unreleased]
8+
### Added
9+
- `tagMessage` allows to create annotated tags when publishing new versions. ([#22](https://github.com/diffplug/spotless-changelog/pull/22))
810

911
## [2.1.2] - 2021-04-10
1012
### Fixed

Diff for: README.md

+1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ spotlessChangelog { // all defaults
171171
// tag and push
172172
tagPrefix 'release/'
173173
commitMessage 'Published release/{{version}}' // {{version}} will be replaced
174+
tagMessage null // default is null (creates lightweight tag); {{changes}} and {{version}} will be replaced
174175
remote 'origin'
175176
branch 'main'
176177
// default value is `yes`, but if you set it to `no`, then it will

Diff for: spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/Changelog.java

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2019-2020 DiffPlug
2+
* Copyright (C) 2019-2021 DiffPlug
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@ public class Changelog {
3535
private static final String VERSION_BEGIN = "\n## [";
3636
private static final String UNRELEASED = VERSION_BEGIN + "Unreleased]";
3737
private static final String DONT_PARSE_BELOW_HERE = "\n<!-- END CHANGELOG -->";
38-
3938
private final boolean windowsNewlines;
4039
private final PoolString dontParse, beforeUnreleased;
4140
private final List<VersionEntry> versionsRaw;
@@ -166,6 +165,15 @@ public static class VersionEntry {
166165

167166
private VersionEntry() {}
168167

168+
private VersionEntry copy() {
169+
VersionEntry copy = new VersionEntry();
170+
copy.version = version;
171+
copy.date = date;
172+
copy.headerMisc = headerMisc;
173+
copy.changes = changes;
174+
return copy;
175+
}
176+
169177
/** Creates a VersionHeader of the given version and date. */
170178
public static VersionEntry versionDate(String version, String date) {
171179
VersionEntry header = new VersionEntry();
@@ -313,7 +321,8 @@ public Changelog releaseUnreleased(String version, String date) {
313321

314322
VersionEntry entry = VersionEntry.versionDate(version, date);
315323
entry.setChanges(unreleased.changes());
316-
unreleased.setChanges("\n");
324+
325+
list.set(0, unreleased.copy().setChanges("\n"));
317326
list.add(1, entry);
318327
});
319328
}

Diff for: spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitActions.java

+18-6
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import java.util.function.Consumer;
2828
import org.eclipse.jgit.api.Git;
2929
import org.eclipse.jgit.api.PushCommand;
30+
import org.eclipse.jgit.api.TagCommand;
3031
import org.eclipse.jgit.api.errors.GitAPIException;
3132
import org.eclipse.jgit.lib.ConfigConstants;
3233
import org.eclipse.jgit.lib.Constants;
@@ -57,7 +58,6 @@ public class GitActions implements AutoCloseable {
5758
repository = new FileRepositoryBuilder()
5859
.findGitDir(changelogFile)
5960
.build();
60-
repository.getWorkTree();
6161
git = new Git(repository);
6262
}
6363

@@ -87,23 +87,35 @@ public void assertNoTag() throws IOException {
8787

8888
/** Adds and commits the changelog. */
8989
public void addAndCommit() throws GitAPIException {
90-
String commitMsg = cfg.commitMessage.replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next());
9190
String path = repository.getWorkTree().toPath().relativize(changelogFile.toPath()).toString();
9291
git.add()
9392
.addFilepattern(path)
9493
.call();
9594
git.commit()
96-
.setMessage(commitMsg)
95+
.setMessage(formatCommitMessage(cfg.commitMessage))
9796
.call();
9897
}
9998

100-
/** Tags and pushes the tag and the branch. */
99+
/** Tags and pushes the tag and the branch. */
101100
public void tagBranchPush() throws GitAPIException {
102-
Ref tagRef = git.tag().setName(tagName()).setAnnotated(false).call();
103-
push(tagRef, RemoteRefUpdate.Status.OK);
101+
TagCommand tagCommand = git.tag().setName(tagName());
102+
if (cfg.tagMessage != null) {
103+
tagCommand.setAnnotated(true).setMessage(formatTagMessage(cfg.tagMessage));
104+
}
105+
push(tagCommand.call(), RemoteRefUpdate.Status.OK);
104106
push(cfg.branch, RemoteRefUpdate.Status.OK);
105107
}
106108

109+
private String formatCommitMessage(final String commitMessage) {
110+
return commitMessage.replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next());
111+
}
112+
113+
private String formatTagMessage(final String tagMessage) {
114+
return formatCommitMessage(tagMessage)
115+
.replace(GitCfg.TAG_MESSAGE_CHANGES, model.changelog().unreleasedChanges())
116+
.replace(GitCfg.COMMIT_MESSAGE_VERSION, model.versions().next());
117+
}
118+
107119
private String tagName() {
108120
return cfg.tagPrefix + model.versions().next();
109121
}

Diff for: spotless-changelog-lib/src/main/java/com/diffplug/spotless/changelog/GitCfg.java

+3
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,14 @@
2222
/** Configuration for committing, tagging, and pushing the next version. */
2323
public class GitCfg {
2424
public static final String COMMIT_MESSAGE_VERSION = "{{version}}";
25+
public static final String TAG_MESSAGE_CHANGES = "{{changes}}";
2526

2627
/** Prefix used for release tags, default is `release/`. */
2728
public String tagPrefix = "release/";
2829
/** Message used for release commits, default is `Published release/{{version}}`. */
2930
public String commitMessage = "Published release/" + COMMIT_MESSAGE_VERSION;
31+
/** Message used in tag, null means lightweight tag. */
32+
public String tagMessage = null;
3033
public String remote = "origin";
3134
public String branch = "main";
3235
public String sshStrictHostKeyChecking = "yes";

Diff for: spotless-changelog-plugin-gradle/src/main/java/com/diffplug/spotless/changelog/gradle/ChangelogExtension.java

+5
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ public void commitMessage(String commitMessage) {
194194
gitCfg.commitMessage = GitCfg.validateCommitMessage(commitMessage);
195195
}
196196

197+
/** Default value is null (creates a lightweight tag) - {{changes}} and {{version}} will be replaced. */
198+
public void tagMessage(String tagMessage) {
199+
gitCfg.tagMessage = tagMessage;
200+
}
201+
197202
/** Default value is 'origin' */
198203
public void remote(String remote) {
199204
gitCfg.remote = remote;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
/*
2+
* Copyright (C) 2019-2021 DiffPlug
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.diffplug.spotless.changelog.gradle;
17+
18+
import static org.junit.Assert.assertEquals;
19+
20+
import java.io.File;
21+
import java.io.IOException;
22+
import java.nio.file.Files;
23+
import java.nio.file.Paths;
24+
import org.eclipse.jgit.api.Git;
25+
import org.eclipse.jgit.api.errors.GitAPIException;
26+
import org.eclipse.jgit.revwalk.RevWalk;
27+
import org.junit.Rule;
28+
import org.junit.Test;
29+
import org.junit.rules.TemporaryFolder;
30+
import org.junit.rules.TestWatcher;
31+
import org.junit.runner.Description;
32+
33+
public class ChangelogPluginPushTest extends GradleHarness {
34+
35+
@Rule
36+
public DeleteOnSuccessTemporaryFolder temporaryFolder = new DeleteOnSuccessTemporaryFolder(new File("build"));
37+
@Rule
38+
public KeepTempFolderOnFailure keepTempFolderOnFailure = new KeepTempFolderOnFailure(temporaryFolder);
39+
40+
@Test
41+
public void verifyAnnotatedTagMessage() throws IOException, GitAPIException {
42+
43+
final String testCaseFolder = "1.0.3-annotatedTag";
44+
File origin = initUpstreamRepo(testCaseFolder);
45+
46+
final File working = temporaryFolder.newFolder("working");
47+
Git git = Git.cloneRepository().setURI(origin.getAbsolutePath())
48+
.setDirectory(working).call();
49+
50+
copyResourceFile(working, testCaseFolder, "CHANGELOG.md");
51+
52+
gradleRunner().withProjectDir(working)/*.withDebug(true)*/
53+
.withArguments("changelogPush").build();
54+
55+
assertEquals("Version is 1.0.3, here are the changes:"
56+
+ "\n\n### Fixed\n"
57+
+ "- this should be in tag message\n",
58+
annotatedTagMessage(git, "release/1.0.3"));
59+
}
60+
61+
private String annotatedTagMessage(Git localGit, final String tagName) throws IOException {
62+
try (RevWalk walk = new RevWalk(localGit.getRepository())) {
63+
return walk.parseTag(
64+
localGit.getRepository().findRef(tagName).getObjectId())
65+
.getFullMessage();
66+
}
67+
}
68+
69+
private File initUpstreamRepo(String testCaseFolder) throws IOException, GitAPIException {
70+
File origin = temporaryFolder.newFolder("origin");
71+
Git git = Git.init().setDirectory(origin).call();
72+
copyResourceFile(origin, "settings.gradle");
73+
copyResourceFile(origin, testCaseFolder, "build.gradle");
74+
git.add().addFilepattern(".").call();
75+
git.commit()
76+
.setMessage("Commit all changes including additions")
77+
.call();
78+
return origin;
79+
}
80+
81+
private void copyResourceFile(File working, String testCaseFolder, String fileName) throws IOException {
82+
Files.copy(Paths.get("src/test/resources", testCaseFolder, fileName), working.toPath().resolve(fileName));
83+
}
84+
85+
private void copyResourceFile(File working, String fileName) throws IOException {
86+
Files.copy(Paths.get("src/test/resources", fileName), working.toPath().resolve(fileName));
87+
}
88+
89+
static class KeepTempFolderOnFailure extends TestWatcher {
90+
private final DeleteOnSuccessTemporaryFolder folder;
91+
92+
KeepTempFolderOnFailure(DeleteOnSuccessTemporaryFolder folder) {
93+
this.folder = folder;
94+
}
95+
96+
@Override
97+
protected void failed(Throwable e, Description description) {
98+
folder.disableDeletion();
99+
}
100+
}
101+
102+
static class DeleteOnSuccessTemporaryFolder extends TemporaryFolder {
103+
104+
boolean canDelete = true;
105+
106+
public DeleteOnSuccessTemporaryFolder(File file) {
107+
super(file);
108+
}
109+
110+
@Override
111+
protected void after() {
112+
if (canDelete)
113+
super.after();
114+
}
115+
116+
public void disableDeletion() {
117+
canDelete = false;
118+
}
119+
}
120+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Changelog
2+
3+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
4+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
5+
6+
## [Unreleased]
7+
8+
### Fixed
9+
- this should be in tag message
10+
11+
## [1.0.2] - 2021-04-23
12+
13+
Initial release.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
id 'com.diffplug.spotless-changelog'
3+
}
4+
5+
spotlessChangelog {
6+
branch 'master'
7+
tagMessage 'Version is {{version}}, here are the changes:{{changes}}'
8+
}

Diff for: spotless-changelog-plugin-gradle/src/test/resources/settings.gradle

Whitespace-only changes.

0 commit comments

Comments
 (0)