mirror of
https://github.com/jlengrand/jreleaser.git
synced 2026-03-10 08:31:24 +00:00
Support closing milestones upon release
This commit is contained in:
@@ -85,6 +85,8 @@ public class Signer {
|
||||
List<FilePair> files = collectArtifacts(context, keyring);
|
||||
if (files.isEmpty()) {
|
||||
context.getLogger().info("No files configured for signing. Skipping");
|
||||
context.getLogger().restorePrefix();
|
||||
context.getLogger().decreaseIndent();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -94,6 +96,8 @@ public class Signer {
|
||||
|
||||
if (files.isEmpty()) {
|
||||
context.getLogger().info("All signatures are up-to-date and valid. Skipping");
|
||||
context.getLogger().restorePrefix();
|
||||
context.getLogger().decreaseIndent();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
private static final String TAG_EARLY_ACCESS = "early-access";
|
||||
|
||||
private final String serviceName;
|
||||
private final Changelog changelog = new Changelog();
|
||||
private final Milestone milestone = new Milestone();
|
||||
private final CommitAuthor commitAuthor = new CommitAuthor();
|
||||
protected Boolean enabled;
|
||||
private String host;
|
||||
private String owner;
|
||||
@@ -54,10 +57,8 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
private String token;
|
||||
private String tagName = "v{{projectVersion}}";
|
||||
private String releaseName = "Release {{tagName}}";
|
||||
private CommitAuthor commitAuthor = new CommitAuthor();
|
||||
private boolean sign;
|
||||
private boolean skipTagging;
|
||||
private Changelog changelog = new Changelog();
|
||||
private boolean overwrite;
|
||||
private boolean allowUploadToExisting;
|
||||
private String apiEndpoint;
|
||||
@@ -94,16 +95,9 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
this.overwrite = service.overwrite;
|
||||
this.allowUploadToExisting = service.allowUploadToExisting;
|
||||
this.apiEndpoint = service.apiEndpoint;
|
||||
this.commitAuthor.setAll(service.commitAuthor);
|
||||
this.changelog.setAll(service.changelog);
|
||||
}
|
||||
|
||||
public void setCachedTagName(String cachedTagName) {
|
||||
this.cachedTagName = cachedTagName;
|
||||
}
|
||||
|
||||
public void setCachedReleaseName(String cachedReleaseName) {
|
||||
this.cachedReleaseName = cachedReleaseName;
|
||||
setCommitAuthor(service.commitAuthor);
|
||||
setChangelog(service.changelog);
|
||||
setMilestone(service.milestone);
|
||||
}
|
||||
|
||||
public String getCanonicalRepoName() {
|
||||
@@ -125,6 +119,8 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
|
||||
if (isBlank(cachedTagName)) {
|
||||
cachedTagName = applyTemplate(new StringReader(tagName), props(project));
|
||||
} else if (cachedTagName.contains("{{")) {
|
||||
cachedTagName = applyTemplate(new StringReader(cachedTagName), props(project));
|
||||
}
|
||||
|
||||
return cachedTagName;
|
||||
@@ -135,7 +131,7 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
return TAG_EARLY_ACCESS;
|
||||
}
|
||||
|
||||
return getResolvedTagName(project);
|
||||
return cachedTagName;
|
||||
}
|
||||
|
||||
public String getResolvedReleaseName(Project project) {
|
||||
@@ -145,11 +141,17 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
|
||||
if (isBlank(cachedReleaseName)) {
|
||||
cachedReleaseName = applyTemplate(new StringReader(releaseName), props(project));
|
||||
} else if (cachedReleaseName.contains("{{")) {
|
||||
cachedReleaseName = applyTemplate(new StringReader(cachedReleaseName), props(project));
|
||||
}
|
||||
|
||||
return cachedReleaseName;
|
||||
}
|
||||
|
||||
public String getEffectiveReleaseName() {
|
||||
return cachedReleaseName;
|
||||
}
|
||||
|
||||
public String getResolvedRepoUrl(Project project) {
|
||||
return applyTemplate(new StringReader(repoUrlFormat), props(project));
|
||||
}
|
||||
@@ -306,7 +308,7 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
|
||||
@Override
|
||||
public void setCommitAuthor(CommitAuthor commitAuthor) {
|
||||
this.commitAuthor = commitAuthor;
|
||||
this.commitAuthor.setAll(commitAuthor);
|
||||
}
|
||||
|
||||
public boolean isSign() {
|
||||
@@ -330,7 +332,15 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
}
|
||||
|
||||
public void setChangelog(Changelog changelog) {
|
||||
this.changelog = changelog;
|
||||
this.changelog.setAll(changelog);
|
||||
}
|
||||
|
||||
public Milestone getMilestone() {
|
||||
return milestone;
|
||||
}
|
||||
|
||||
public void setMilestone(Milestone milestone) {
|
||||
this.milestone.setAll(milestone);
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
@@ -381,11 +391,11 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
map.put("allowUploadToExisting", allowUploadToExisting);
|
||||
map.put("apiEndpoint", apiEndpoint);
|
||||
map.put("changelog", changelog.asMap());
|
||||
map.put("milestone", milestone.asMap());
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> props(Project project) {
|
||||
public Map<String, Object> props(Project project) {
|
||||
// duplicate from JReleaserModel to avoid endless recursion
|
||||
Map<String, Object> props = new LinkedHashMap<>();
|
||||
props.put(Constants.KEY_PROJECT_NAME, project.getName());
|
||||
@@ -412,6 +422,7 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
props.put(Constants.KEY_CANONICAL_REPO_NAME, getCanonicalRepoName());
|
||||
props.put(Constants.KEY_TAG_NAME, project.isSnapshot() ? TAG_EARLY_ACCESS : cachedTagName);
|
||||
props.put(Constants.KEY_RELEASE_NAME, cachedReleaseName);
|
||||
props.put(Constants.KEY_MILESTONE_NAME, milestone.getEffectiveName());
|
||||
return props;
|
||||
}
|
||||
|
||||
@@ -423,7 +434,8 @@ public abstract class GitService implements Releaser, CommitAuthorProvider, Owne
|
||||
props.put(Constants.KEY_REVERSE_REPO_HOST, getReverseRepoHost());
|
||||
props.put(Constants.KEY_CANONICAL_REPO_NAME, getCanonicalRepoName());
|
||||
props.put(Constants.KEY_TAG_NAME, getEffectiveTagName(project));
|
||||
props.put(Constants.KEY_RELEASE_NAME, getResolvedReleaseName(project));
|
||||
props.put(Constants.KEY_RELEASE_NAME, getEffectiveReleaseName());
|
||||
props.put(Constants.KEY_MILESTONE_NAME, milestone.getEffectiveName());
|
||||
props.put(Constants.KEY_REPO_URL, getResolvedRepoUrl(project));
|
||||
props.put(Constants.KEY_COMMIT_URL, getResolvedCommitUrl(project));
|
||||
props.put(Constants.KEY_RELEASE_NOTES_URL, getResolvedReleaseNotesUrl(project));
|
||||
|
||||
@@ -212,7 +212,8 @@ public class JReleaserModel implements Domain {
|
||||
props.put(Constants.KEY_REPO_NAME, service.getName());
|
||||
props.put(Constants.KEY_REPO_BRANCH, service.getBranch());
|
||||
props.put(Constants.KEY_TAG_NAME, service.getEffectiveTagName(project));
|
||||
props.put(Constants.KEY_RELEASE_NAME, service.getResolvedReleaseName(project));
|
||||
props.put(Constants.KEY_RELEASE_NAME, service.getEffectiveReleaseName());
|
||||
props.put(Constants.KEY_MILESTONE_NAME, service.getMilestone().getEffectiveName());
|
||||
props.put(Constants.KEY_REVERSE_REPO_HOST, service.getReverseRepoHost());
|
||||
props.put(Constants.KEY_CANONICAL_REPO_NAME, service.getCanonicalRepoName());
|
||||
props.put(Constants.KEY_REPO_URL, service.getResolvedRepoUrl(project));
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.model;
|
||||
|
||||
import org.jreleaser.util.Env;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jreleaser.util.MustacheUtils.applyTemplate;
|
||||
import static org.jreleaser.util.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Milestone implements Domain {
|
||||
public static final String MILESTONE_NAME = "MILESTONE_NAME";
|
||||
|
||||
private Boolean close;
|
||||
private String name = "{{ tagName }}";
|
||||
|
||||
private String cachedName;
|
||||
|
||||
void setAll(Milestone changelog) {
|
||||
this.close = changelog.close;
|
||||
this.name = changelog.name;
|
||||
}
|
||||
|
||||
public String getEffectiveName() {
|
||||
return cachedName;
|
||||
}
|
||||
|
||||
public String getResolvedName(Map<String, Object> props) {
|
||||
if (isBlank(cachedName)) {
|
||||
cachedName = Env.resolve(MILESTONE_NAME, cachedName);
|
||||
}
|
||||
|
||||
if (isBlank(cachedName)) {
|
||||
cachedName = applyTemplate(new StringReader(name), props);
|
||||
} else if (cachedName.contains("{{")) {
|
||||
cachedName = applyTemplate(new StringReader(cachedName), props);
|
||||
}
|
||||
|
||||
return cachedName;
|
||||
}
|
||||
|
||||
public Boolean isClose() {
|
||||
return close == null || close;
|
||||
}
|
||||
|
||||
public void setClose(Boolean close) {
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
public boolean isCloseSet() {
|
||||
return close != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Map<String, Object> asMap() {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("name", name);
|
||||
map.put("close", isClose());
|
||||
return map;
|
||||
}
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import java.util.List;
|
||||
|
||||
import static org.jreleaser.model.GitService.RELEASE_NAME;
|
||||
import static org.jreleaser.model.GitService.TAG_NAME;
|
||||
import static org.jreleaser.model.Milestone.MILESTONE_NAME;
|
||||
import static org.jreleaser.util.StringUtils.isBlank;
|
||||
|
||||
/**
|
||||
@@ -92,9 +93,22 @@ public abstract class GitServiceValidator extends Validator {
|
||||
service.getCommitAuthor().setEmail("jreleaser-bot@jreleaser.org");
|
||||
}
|
||||
|
||||
// milestone
|
||||
service.getMilestone().setName(
|
||||
checkProperty(context.getModel().getEnvironment(),
|
||||
MILESTONE_NAME,
|
||||
service.getServiceName() + ".milestone.name",
|
||||
service.getMilestone().getName(),
|
||||
errors));
|
||||
|
||||
if (isBlank(service.getMilestone().getName())) {
|
||||
service.getMilestone().setName("{{ tagName }}");
|
||||
}
|
||||
|
||||
// eager resolve
|
||||
service.getResolvedTagName(project);
|
||||
service.getResolvedReleaseName(project);
|
||||
service.getMilestone().getResolvedName(service.props(project));
|
||||
|
||||
if (project.isSnapshot()) {
|
||||
service.setReleaseName(StringUtils.capitalize(project.getName()) + " Early-Access");
|
||||
|
||||
@@ -17,30 +17,32 @@
|
||||
*/
|
||||
package org.jreleaser.util;
|
||||
|
||||
import java.util.Stack;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public abstract class AbstractJReleaserLogger implements JReleaserLogger {
|
||||
private final Stack<String> prefix = new Stack<>();
|
||||
private String indent = "";
|
||||
private String prefix = null;
|
||||
private String previousPrefix = null;
|
||||
|
||||
@Override
|
||||
public void reset() {
|
||||
this.prefix = this.previousPrefix = null;
|
||||
this.prefix.clear();
|
||||
this.indent = "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPrefix(String prefix) {
|
||||
this.previousPrefix = this.prefix;
|
||||
this.prefix = prefix;
|
||||
this.prefix.push(prefix);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restorePrefix() {
|
||||
this.prefix = this.previousPrefix;
|
||||
if (!this.prefix.isEmpty()) {
|
||||
this.prefix.pop();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -56,6 +58,6 @@ public abstract class AbstractJReleaserLogger implements JReleaserLogger {
|
||||
}
|
||||
|
||||
protected String formatMessage(String message) {
|
||||
return indent + (prefix != null ? "[" + prefix + "] " : "") + message;
|
||||
return indent + (!prefix.isEmpty() ? "[" + prefix.peek() + "] " : "") + message;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,6 +58,7 @@ public interface Constants {
|
||||
String KEY_REPO_BRANCH = "repoBranch";
|
||||
String KEY_TAG_NAME = "tagName";
|
||||
String KEY_RELEASE_NAME = "releaseName";
|
||||
String KEY_MILESTONE_NAME = "milestoneName";
|
||||
String KEY_CANONICAL_REPO_NAME = "repoCanonicalName";
|
||||
String KEY_REPO_URL = "repoUrl";
|
||||
String KEY_COMMIT_URL = "commitsUrl";
|
||||
|
||||
@@ -35,6 +35,7 @@ import java.util.Properties;
|
||||
|
||||
import static org.jreleaser.util.Constants.KEY_COMMIT_FULL_HASH;
|
||||
import static org.jreleaser.util.Constants.KEY_COMMIT_SHORT_HASH;
|
||||
import static org.jreleaser.util.Constants.KEY_MILESTONE_NAME;
|
||||
import static org.jreleaser.util.Constants.KEY_PROJECT_SNAPSHOT;
|
||||
import static org.jreleaser.util.Constants.KEY_PROJECT_VERSION;
|
||||
import static org.jreleaser.util.Constants.KEY_RELEASE_NAME;
|
||||
@@ -102,7 +103,8 @@ class WorkflowImpl implements Workflow {
|
||||
props.put(KEY_PROJECT_VERSION, project.getResolvedVersion());
|
||||
props.put(KEY_PROJECT_SNAPSHOT, String.valueOf(project.isSnapshot()));
|
||||
props.put(KEY_TAG_NAME, model.getRelease().getGitService().getEffectiveTagName(project));
|
||||
props.put(KEY_RELEASE_NAME, model.getRelease().getGitService().getResolvedReleaseName(project));
|
||||
props.put(KEY_RELEASE_NAME, model.getRelease().getGitService().getEffectiveReleaseName());
|
||||
props.put(KEY_MILESTONE_NAME, model.getRelease().getGitService().getMilestone().getEffectiveName());
|
||||
|
||||
Map<String, Object> resolvedExtraProperties = project.getResolvedExtraProperties();
|
||||
safePut("project" + capitalize(KEY_VERSION_MAJOR), resolvedExtraProperties, props);
|
||||
|
||||
@@ -66,6 +66,10 @@ interface GitService extends Releaser {
|
||||
|
||||
void changelog(Action<? super Changelog> action)
|
||||
|
||||
Milestone getMilestone()
|
||||
|
||||
void milestone(Action<? super Milestone> action)
|
||||
|
||||
CommitAuthor getCommitAuthor()
|
||||
|
||||
void commitAuthor(Action<? super CommitAuthor> action)
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.gradle.plugin.dsl
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.gradle.api.provider.Property
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CompileStatic
|
||||
interface Milestone {
|
||||
Property<Boolean> getClose()
|
||||
|
||||
Property<Boolean> getName()
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import org.gradle.api.tasks.Internal
|
||||
import org.jreleaser.gradle.plugin.dsl.Changelog
|
||||
import org.jreleaser.gradle.plugin.dsl.CommitAuthor
|
||||
import org.jreleaser.gradle.plugin.dsl.GitService
|
||||
import org.jreleaser.gradle.plugin.dsl.Milestone
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -108,6 +109,11 @@ abstract class AbstractGitService implements GitService {
|
||||
action.execute(changelog)
|
||||
}
|
||||
|
||||
@Override
|
||||
void milestone(Action<? super Milestone> action) {
|
||||
action.execute(milestone)
|
||||
}
|
||||
|
||||
@Override
|
||||
void commitAuthor(Action<? super CommitAuthor> action) {
|
||||
action.execute(commitAuthor)
|
||||
|
||||
@@ -37,6 +37,7 @@ class GiteaImpl extends AbstractGitService implements Gitea {
|
||||
final Property<Boolean> draft
|
||||
final Property<Boolean> prerelease
|
||||
final ChangelogImpl changelog
|
||||
final MilestoneImpl milestone
|
||||
final CommitAuthorImpl commitAuthor
|
||||
|
||||
@Inject
|
||||
@@ -47,6 +48,7 @@ class GiteaImpl extends AbstractGitService implements Gitea {
|
||||
prerelease = objects.property(Boolean).convention(Providers.notDefined())
|
||||
|
||||
changelog = objects.newInstance(ChangelogImpl, objects)
|
||||
milestone = objects.newInstance(MilestoneImpl, objects)
|
||||
commitAuthor = objects.newInstance(CommitAuthorImpl, objects)
|
||||
}
|
||||
|
||||
@@ -57,6 +59,7 @@ class GiteaImpl extends AbstractGitService implements Gitea {
|
||||
draft.present ||
|
||||
prerelease.present ||
|
||||
changelog.isSet() ||
|
||||
milestone.isSet() ||
|
||||
commitAuthor.isSet()
|
||||
}
|
||||
|
||||
@@ -67,6 +70,7 @@ class GiteaImpl extends AbstractGitService implements Gitea {
|
||||
service.draft = draft.getOrElse(false)
|
||||
service.prerelease = prerelease.getOrElse(false)
|
||||
if (changelog.isSet()) service.changelog = changelog.toModel()
|
||||
if (milestone.isSet()) service.milestone = milestone.toModel()
|
||||
if (commitAuthor.isSet()) service.commitAuthor = commitAuthor.toModel()
|
||||
service
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ class GithubImpl extends AbstractGitService implements Github {
|
||||
final Property<Boolean> draft
|
||||
final Property<Boolean> prerelease
|
||||
final ChangelogImpl changelog
|
||||
final MilestoneImpl milestone
|
||||
final CommitAuthorImpl commitAuthor
|
||||
|
||||
@Inject
|
||||
@@ -47,6 +48,7 @@ class GithubImpl extends AbstractGitService implements Github {
|
||||
prerelease = objects.property(Boolean).convention(Providers.notDefined())
|
||||
|
||||
changelog = objects.newInstance(ChangelogImpl, objects)
|
||||
milestone = objects.newInstance(MilestoneImpl, objects)
|
||||
commitAuthor = objects.newInstance(CommitAuthorImpl, objects)
|
||||
}
|
||||
|
||||
@@ -57,6 +59,7 @@ class GithubImpl extends AbstractGitService implements Github {
|
||||
draft.present ||
|
||||
prerelease.present ||
|
||||
changelog.isSet() ||
|
||||
milestone.isSet() ||
|
||||
commitAuthor.isSet()
|
||||
}
|
||||
|
||||
@@ -67,6 +70,7 @@ class GithubImpl extends AbstractGitService implements Github {
|
||||
service.draft = draft.getOrElse(false)
|
||||
service.prerelease = prerelease.getOrElse(false)
|
||||
if (changelog.isSet()) service.changelog = changelog.toModel()
|
||||
if (milestone.isSet()) service.milestone = milestone.toModel()
|
||||
if (commitAuthor.isSet()) service.commitAuthor = commitAuthor.toModel()
|
||||
service
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import javax.inject.Inject
|
||||
class GitlabImpl extends AbstractGitService implements Gitlab {
|
||||
final Property<String> ref
|
||||
final ChangelogImpl changelog
|
||||
final MilestoneImpl milestone
|
||||
final CommitAuthorImpl commitAuthor
|
||||
|
||||
@Inject
|
||||
@@ -43,6 +44,7 @@ class GitlabImpl extends AbstractGitService implements Gitlab {
|
||||
ref = objects.property(String).convention(Providers.notDefined())
|
||||
|
||||
changelog = objects.newInstance(ChangelogImpl, objects)
|
||||
milestone = objects.newInstance(MilestoneImpl, objects)
|
||||
commitAuthor = objects.newInstance(CommitAuthorImpl, objects)
|
||||
}
|
||||
|
||||
@@ -51,6 +53,7 @@ class GitlabImpl extends AbstractGitService implements Gitlab {
|
||||
super.isSet() ||
|
||||
ref.present ||
|
||||
changelog.isSet() ||
|
||||
milestone.isSet() ||
|
||||
commitAuthor.isSet()
|
||||
}
|
||||
|
||||
@@ -59,6 +62,7 @@ class GitlabImpl extends AbstractGitService implements Gitlab {
|
||||
toModel(service)
|
||||
if (ref.present) service.ref = ref.get()
|
||||
if (changelog.isSet()) service.changelog = changelog.toModel()
|
||||
if (milestone.isSet()) service.milestone = milestone.toModel()
|
||||
if (commitAuthor.isSet()) service.commitAuthor = commitAuthor.toModel()
|
||||
service
|
||||
}
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.gradle.plugin.internal.dsl
|
||||
|
||||
import groovy.transform.CompileStatic
|
||||
import org.gradle.api.internal.provider.Providers
|
||||
import org.gradle.api.model.ObjectFactory
|
||||
import org.gradle.api.provider.Property
|
||||
import org.gradle.api.tasks.Internal
|
||||
import org.jreleaser.gradle.plugin.dsl.Milestone
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@CompileStatic
|
||||
class MilestoneImpl implements Milestone {
|
||||
final Property<Boolean> close
|
||||
final Property<String> name
|
||||
|
||||
@Inject
|
||||
MilestoneImpl(ObjectFactory objects) {
|
||||
close = objects.property(Boolean).convention(Providers.notDefined())
|
||||
name = objects.property(String).convention(Providers.notDefined())
|
||||
}
|
||||
|
||||
@Internal
|
||||
boolean isSet() {
|
||||
close.present ||
|
||||
name.present
|
||||
}
|
||||
|
||||
org.jreleaser.model.Milestone toModel() {
|
||||
org.jreleaser.model.Milestone milestone = new org.jreleaser.model.Milestone()
|
||||
if (close.present) milestone.close = close.get()
|
||||
if (name.present) milestone.name = name.get()
|
||||
milestone
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,9 @@ package org.jreleaser.maven.plugin;
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public abstract class GitService implements Releaser {
|
||||
private final CommitAuthor commitAuthor = new CommitAuthor();
|
||||
private final Changelog changelog = new Changelog();
|
||||
private final Milestone milestone = new Milestone();
|
||||
protected Boolean enabled;
|
||||
private String host;
|
||||
private String owner;
|
||||
@@ -36,10 +39,8 @@ public abstract class GitService implements Releaser {
|
||||
private String token;
|
||||
private String tagName;
|
||||
private String releaseName;
|
||||
private CommitAuthor commitAuthor = new CommitAuthor();
|
||||
private boolean sign;
|
||||
private boolean skipTagging;
|
||||
private Changelog changelog = new Changelog();
|
||||
private boolean overwrite;
|
||||
private boolean allowUploadToExisting;
|
||||
private String apiEndpoint;
|
||||
@@ -59,13 +60,14 @@ public abstract class GitService implements Releaser {
|
||||
this.token = service.token;
|
||||
this.tagName = service.tagName;
|
||||
this.releaseName = service.releaseName;
|
||||
this.commitAuthor.setAll(service.commitAuthor);
|
||||
this.sign = service.sign;
|
||||
this.skipTagging = service.skipTagging;
|
||||
this.overwrite = service.overwrite;
|
||||
this.allowUploadToExisting = service.allowUploadToExisting;
|
||||
this.apiEndpoint = service.apiEndpoint;
|
||||
this.changelog.setAll(service.changelog);
|
||||
setCommitAuthor(service.commitAuthor);
|
||||
setChangelog(service.changelog);
|
||||
setMilestone(service.milestone);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,7 +194,7 @@ public abstract class GitService implements Releaser {
|
||||
}
|
||||
|
||||
public void setCommitAuthor(CommitAuthor commitAuthor) {
|
||||
this.commitAuthor = commitAuthor;
|
||||
this.commitAuthor.setAll(commitAuthor);
|
||||
}
|
||||
|
||||
public boolean isSign() {
|
||||
@@ -216,7 +218,15 @@ public abstract class GitService implements Releaser {
|
||||
}
|
||||
|
||||
public void setChangelog(Changelog changelog) {
|
||||
this.changelog = changelog;
|
||||
this.changelog.setAll(changelog);
|
||||
}
|
||||
|
||||
public Milestone getMilestone() {
|
||||
return milestone;
|
||||
}
|
||||
|
||||
public void setMilestone(Milestone milestone) {
|
||||
this.milestone.setAll(milestone);
|
||||
}
|
||||
|
||||
public boolean isOverwrite() {
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.maven.plugin;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class Milestone {
|
||||
private Boolean close;
|
||||
private String name;
|
||||
|
||||
void setAll(Milestone changelog) {
|
||||
this.close = changelog.close;
|
||||
this.name = changelog.name;
|
||||
}
|
||||
|
||||
public Boolean isClose() {
|
||||
return close == null || close;
|
||||
}
|
||||
|
||||
public void setClose(Boolean close) {
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
public boolean isCloseSet() {
|
||||
return close != null;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
@@ -38,6 +38,7 @@ import org.jreleaser.maven.plugin.Java;
|
||||
import org.jreleaser.maven.plugin.Jbang;
|
||||
import org.jreleaser.maven.plugin.Jreleaser;
|
||||
import org.jreleaser.maven.plugin.Mail;
|
||||
import org.jreleaser.maven.plugin.Milestone;
|
||||
import org.jreleaser.maven.plugin.Packagers;
|
||||
import org.jreleaser.maven.plugin.Plug;
|
||||
import org.jreleaser.maven.plugin.Project;
|
||||
@@ -176,6 +177,7 @@ public final class JReleaserModelConverter {
|
||||
s.setAllowUploadToExisting(service.isAllowUploadToExisting());
|
||||
s.setApiEndpoint(service.getApiEndpoint());
|
||||
s.setChangelog(convertChangelog(service.getChangelog()));
|
||||
s.setMilestone(convertMilestone(service.getMilestone()));
|
||||
}
|
||||
|
||||
private static org.jreleaser.model.CommitAuthor convertCommitAuthor(CommitAuthor commitAuthor) {
|
||||
@@ -193,6 +195,13 @@ public final class JReleaserModelConverter {
|
||||
return c;
|
||||
}
|
||||
|
||||
private static org.jreleaser.model.Milestone convertMilestone(Milestone milestone) {
|
||||
org.jreleaser.model.Milestone m = new org.jreleaser.model.Milestone();
|
||||
m.setClose(milestone.isClose());
|
||||
m.setName(milestone.getName());
|
||||
return m;
|
||||
}
|
||||
|
||||
private static org.jreleaser.model.Packagers convertPackagers(Packagers packagers) {
|
||||
org.jreleaser.model.Packagers p = new org.jreleaser.model.Packagers();
|
||||
if (packagers.getBrew().isSet()) p.setBrew(convertBrew(packagers.getBrew()));
|
||||
|
||||
@@ -26,6 +26,10 @@ dependencies {
|
||||
|
||||
api "io.github.openfeign:feign-core:$feignVersion"
|
||||
api "io.github.openfeign:feign-jackson:$feignVersion"
|
||||
api("io.github.openfeign:feign-httpclient:$feignVersion") {
|
||||
exclude group: 'commons-logging', module: 'commons-logging'
|
||||
}
|
||||
api "org.slf4j:jcl-over-slf4j:$slf4jVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
api "io.github.openfeign.form:feign-form:$feignFormVersion"
|
||||
|
||||
@@ -26,12 +26,14 @@ import feign.Feign;
|
||||
import feign.Request;
|
||||
import feign.form.FormData;
|
||||
import feign.form.FormEncoder;
|
||||
import feign.httpclient.ApacheHttpClient;
|
||||
import feign.jackson.JacksonDecoder;
|
||||
import feign.jackson.JacksonEncoder;
|
||||
import org.apache.tika.Tika;
|
||||
import org.apache.tika.mime.MediaType;
|
||||
import org.jreleaser.sdk.gitea.api.GiteaAPI;
|
||||
import org.jreleaser.sdk.gitea.api.GiteaAPIException;
|
||||
import org.jreleaser.sdk.gitea.api.GtMilestone;
|
||||
import org.jreleaser.sdk.gitea.api.GtOrganization;
|
||||
import org.jreleaser.sdk.gitea.api.GtRelease;
|
||||
import org.jreleaser.sdk.gitea.api.GtRepository;
|
||||
@@ -43,10 +45,10 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static org.jreleaser.util.StringUtils.isBlank;
|
||||
import static org.jreleaser.util.StringUtils.requireNonBlank;
|
||||
|
||||
/**
|
||||
@@ -80,6 +82,7 @@ class Gitea {
|
||||
|
||||
this.logger = logger;
|
||||
this.api = Feign.builder()
|
||||
.client(new ApacheHttpClient())
|
||||
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
|
||||
.decoder(new JacksonDecoder(objectMapper))
|
||||
.requestInterceptor(template -> template.header("Authorization", String.format("token %s", token)))
|
||||
@@ -101,6 +104,33 @@ class Gitea {
|
||||
}
|
||||
}
|
||||
|
||||
Optional<GtMilestone> findMilestoneByName(String owner, String repo, String milestoneName) {
|
||||
logger.debug("Lookup milestone '{}' on {}/{}", milestoneName, owner, repo);
|
||||
|
||||
try {
|
||||
GtMilestone milestone = api.findMilestoneByTitle(owner, repo, milestoneName);
|
||||
|
||||
if (milestone == null) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
return "open".equals(milestone.getState()) ? Optional.of(milestone) : Optional.empty();
|
||||
} catch (GiteaAPIException e) {
|
||||
if (e.isNotFound()) {
|
||||
// ok
|
||||
return Optional.empty();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void closeMilestone(String owner, String repo, GtMilestone milestone) throws IOException {
|
||||
logger.debug("Closing milestone '{}' on {}/{}", milestone.getTitle(), owner, repo);
|
||||
|
||||
api.updateMilestone(CollectionUtils.<String, Object>map()
|
||||
.e("state", "closed"), owner, repo, milestone.getId());
|
||||
}
|
||||
|
||||
GtRepository createRepository(String owner, String repo) {
|
||||
logger.debug("Creating repository {}/{}", owner, repo);
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jreleaser.model.releaser.spi.Releaser;
|
||||
import org.jreleaser.model.releaser.spi.Repository;
|
||||
import org.jreleaser.sdk.git.GitSdk;
|
||||
import org.jreleaser.sdk.gitea.api.GiteaAPIException;
|
||||
import org.jreleaser.sdk.gitea.api.GtMilestone;
|
||||
import org.jreleaser.sdk.gitea.api.GtRelease;
|
||||
import org.jreleaser.sdk.gitea.api.GtRepository;
|
||||
|
||||
@@ -31,6 +32,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
@@ -123,20 +125,30 @@ public class GiteaReleaser implements Releaser {
|
||||
}
|
||||
|
||||
// local tag
|
||||
if (deleteTags || !context.getModel().getRelease().getGitService().isSkipTagging()) {
|
||||
if (deleteTags || !gitea.isSkipTagging()) {
|
||||
context.getLogger().debug("Tagging local repository with {}", tagName);
|
||||
GitSdk.of(context).tag(tagName, true);
|
||||
}
|
||||
|
||||
// remote tag/release
|
||||
GtRelease release = new GtRelease();
|
||||
release.setName(gitea.getResolvedReleaseName(context.getModel().getProject()));
|
||||
release.setName(gitea.getEffectiveReleaseName());
|
||||
release.setTagName(gitea.getEffectiveTagName(context.getModel().getProject()));
|
||||
release.setTargetCommitish(gitea.getTargetCommitish());
|
||||
release.setBody(changelog);
|
||||
|
||||
release = api.createRelease(gitea.getOwner(), gitea.getName(), release);
|
||||
api.uploadAssets(gitea.getOwner(), gitea.getName(), release, assets);
|
||||
|
||||
Optional<GtMilestone> milestone = api.findMilestoneByName(
|
||||
gitea.getOwner(),
|
||||
gitea.getName(),
|
||||
gitea.getMilestone().getEffectiveName());
|
||||
if (milestone.isPresent()) {
|
||||
api.closeMilestone(gitea.getOwner(),
|
||||
gitea.getName(),
|
||||
milestone.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTags(Gitea api, String owner, String repo, String tagName) {
|
||||
|
||||
@@ -37,11 +37,11 @@ public interface GiteaAPI {
|
||||
|
||||
@RequestLine("POST /orgs/{org}/repos")
|
||||
@Headers("Content-Type: application/json")
|
||||
GtRepository createRepository(Map<String,Object> data, @Param("org") String org);
|
||||
GtRepository createRepository(Map<String, Object> data, @Param("org") String org);
|
||||
|
||||
@RequestLine("POST /user/repos")
|
||||
@Headers("Content-Type: application/json")
|
||||
GtRepository createRepository(Map<String,Object> data);
|
||||
GtRepository createRepository(Map<String, Object> data);
|
||||
|
||||
@RequestLine("GET /repos/{owner}/{repo}/releases/tags/{tag}")
|
||||
GtRelease getReleaseByTagName(@Param("owner") String owner, @Param("repo") String repo, @Param("tag") String tag);
|
||||
@@ -59,4 +59,11 @@ public interface GiteaAPI {
|
||||
@RequestLine("POST /repos/{owner}/{repo}/releases/{id}/assets")
|
||||
@Headers("Content-Type: multipart/form-data")
|
||||
GtAttachment uploadAsset(@Param("owner") String owner, @Param("repo") String repo, @Param("id") Integer id, @Param("attachment") FormData file);
|
||||
|
||||
@RequestLine("GET /repos/{owner}/{repo}/milestones/{milestoneName}")
|
||||
GtMilestone findMilestoneByTitle(@Param("owner") String owner, @Param("repo") String repo, @Param("milestoneName") String milestoneName);
|
||||
|
||||
@RequestLine("PATCH /repos/{owner}/{repo}/milestones/{id}")
|
||||
@Headers("Content-Type: application/json")
|
||||
void updateMilestone(Map<String, Object> params, @Param("owner") String owner, @Param("repo") String repo, @Param("id") Integer id);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.sdk.gitea.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GtMilestone {
|
||||
private Integer id;
|
||||
private String title;
|
||||
private String state;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import org.kohsuke.github.GHAsset;
|
||||
import org.kohsuke.github.GHDiscussion;
|
||||
import org.kohsuke.github.GHException;
|
||||
import org.kohsuke.github.GHFileNotFoundException;
|
||||
import org.kohsuke.github.GHIssueState;
|
||||
import org.kohsuke.github.GHMilestone;
|
||||
import org.kohsuke.github.GHOrganization;
|
||||
import org.kohsuke.github.GHRelease;
|
||||
import org.kohsuke.github.GHReleaseBuilder;
|
||||
@@ -31,6 +33,7 @@ import org.kohsuke.github.GHRepository;
|
||||
import org.kohsuke.github.GHTeam;
|
||||
import org.kohsuke.github.GitHub;
|
||||
import org.kohsuke.github.GitHubBuilder;
|
||||
import org.kohsuke.github.PagedIterable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
@@ -93,6 +96,22 @@ class Github {
|
||||
.create();
|
||||
}
|
||||
|
||||
Optional<GHMilestone> findMilestoneByName(String owner, String repo, String milestoneName) throws IOException {
|
||||
logger.debug("Lookup milestone '{}' on {}/{}", milestoneName, owner, repo);
|
||||
|
||||
GHRepository repository = findRepository(owner, repo);
|
||||
PagedIterable<GHMilestone> milestones = repository.listMilestones(GHIssueState.OPEN);
|
||||
return StreamSupport.stream(milestones.spliterator(), false)
|
||||
.filter(m -> milestoneName.equals(m.getTitle()))
|
||||
.findFirst();
|
||||
}
|
||||
|
||||
void closeMilestone(String owner, String repo, GHMilestone milestone) throws IOException {
|
||||
logger.debug("Closing milestone '{}' on {}/{}", milestone.getTitle(), owner, repo);
|
||||
|
||||
milestone.close();
|
||||
}
|
||||
|
||||
GHRelease findReleaseByTag(String repo, String tagName) throws IOException {
|
||||
logger.debug("Fetching release on {} with tag {}", repo, tagName);
|
||||
return github.getRepository(repo)
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.jreleaser.model.releaser.spi.ReleaseException;
|
||||
import org.jreleaser.model.releaser.spi.Releaser;
|
||||
import org.jreleaser.model.releaser.spi.Repository;
|
||||
import org.jreleaser.sdk.git.GitSdk;
|
||||
import org.kohsuke.github.GHMilestone;
|
||||
import org.kohsuke.github.GHRelease;
|
||||
import org.kohsuke.github.GHRepository;
|
||||
|
||||
@@ -30,6 +31,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
@@ -120,7 +122,7 @@ public class GithubReleaser implements Releaser {
|
||||
}
|
||||
|
||||
// local tag
|
||||
if (deleteTags || !context.getModel().getRelease().getGitService().isSkipTagging()) {
|
||||
if (deleteTags || !github.isSkipTagging()) {
|
||||
context.getLogger().debug("Tagging local repository with {}", tagName);
|
||||
GitSdk.of(context).tag(tagName, true);
|
||||
}
|
||||
@@ -129,12 +131,22 @@ public class GithubReleaser implements Releaser {
|
||||
GHRelease release = api.createRelease(github.getCanonicalRepoName(),
|
||||
github.getEffectiveTagName(context.getModel().getProject()))
|
||||
.commitish(github.getTargetCommitish())
|
||||
.name(github.getResolvedReleaseName(context.getModel().getProject()))
|
||||
.name(github.getEffectiveReleaseName())
|
||||
.draft(github.isDraft())
|
||||
.prerelease(github.isPrerelease())
|
||||
.body(changelog)
|
||||
.create();
|
||||
api.uploadAssets(release, assets);
|
||||
|
||||
Optional<GHMilestone> milestone = api.findMilestoneByName(
|
||||
github.getOwner(),
|
||||
github.getName(),
|
||||
github.getMilestone().getEffectiveName());
|
||||
if (milestone.isPresent()) {
|
||||
api.closeMilestone(github.getOwner(),
|
||||
github.getName(),
|
||||
milestone.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTags(Github api, String repo, String tagName) {
|
||||
|
||||
@@ -33,6 +33,7 @@ import org.apache.tika.mime.MediaType;
|
||||
import org.jreleaser.sdk.gitlab.api.FileUpload;
|
||||
import org.jreleaser.sdk.gitlab.api.GitlabAPI;
|
||||
import org.jreleaser.sdk.gitlab.api.GitlabAPIException;
|
||||
import org.jreleaser.sdk.gitlab.api.Milestone;
|
||||
import org.jreleaser.sdk.gitlab.api.Project;
|
||||
import org.jreleaser.sdk.gitlab.api.Release;
|
||||
import org.jreleaser.sdk.gitlab.api.User;
|
||||
@@ -44,6 +45,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
@@ -114,6 +116,40 @@ class Gitlab {
|
||||
return projects.get(0);
|
||||
}
|
||||
|
||||
Optional<Milestone> findMilestoneByName(String owner, String repo, String milestoneName) throws IOException {
|
||||
logger.debug("Lookup milestone '{}' on {}/{}", milestoneName, owner, repo);
|
||||
|
||||
Project project = getProject(repo);
|
||||
|
||||
try {
|
||||
List<Milestone> milestones = api.findMilestoneByTitle(project.getId(), CollectionUtils.<String, Object>map()
|
||||
.e("title", milestoneName));
|
||||
|
||||
if (milestones == null || milestones.isEmpty()) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Milestone milestone = milestones.get(0);
|
||||
return "active".equals(milestone.getState()) ? Optional.of(milestone) : Optional.empty();
|
||||
} catch (GitlabAPIException e) {
|
||||
if (e.isNotFound() || e.isForbidden()) {
|
||||
// ok
|
||||
return Optional.empty();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void closeMilestone(String owner, String repo, Milestone milestone) throws IOException {
|
||||
logger.debug("Closing milestone '{}' on {}/{}", milestone.getTitle(), owner, repo);
|
||||
|
||||
Project project = getProject(repo);
|
||||
|
||||
api.updateMilestone(CollectionUtils.<String, Object>map()
|
||||
.e("state_event", "close"),
|
||||
project.getId(), milestone.getId());
|
||||
}
|
||||
|
||||
Project createProject(String owner, String repo) throws IOException {
|
||||
logger.debug("Creating project {}/{}", owner, repo);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jreleaser.model.releaser.spi.Repository;
|
||||
import org.jreleaser.sdk.git.GitSdk;
|
||||
import org.jreleaser.sdk.gitlab.api.FileUpload;
|
||||
import org.jreleaser.sdk.gitlab.api.GitlabAPIException;
|
||||
import org.jreleaser.sdk.gitlab.api.Milestone;
|
||||
import org.jreleaser.sdk.gitlab.api.Project;
|
||||
import org.jreleaser.sdk.gitlab.api.Release;
|
||||
|
||||
@@ -32,6 +33,7 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
@@ -134,7 +136,7 @@ public class GitlabReleaser implements Releaser {
|
||||
}
|
||||
|
||||
// local tag
|
||||
if (deleteTags || !context.getModel().getRelease().getGitService().isSkipTagging()) {
|
||||
if (deleteTags || !gitlab.isSkipTagging()) {
|
||||
context.getLogger().debug("Tagging local repository with {}", tagName);
|
||||
GitSdk.of(context).tag(tagName, true);
|
||||
}
|
||||
@@ -142,7 +144,7 @@ public class GitlabReleaser implements Releaser {
|
||||
List<FileUpload> uploads = api.uploadAssets(gitlab.getOwner(), gitlab.getName(), assets);
|
||||
|
||||
Release release = new Release();
|
||||
release.setName(gitlab.getResolvedReleaseName(context.getModel().getProject()));
|
||||
release.setName(gitlab.getEffectiveReleaseName());
|
||||
release.setTagName(gitlab.getEffectiveTagName(context.getModel().getProject()));
|
||||
release.setRef(gitlab.getRef());
|
||||
release.setDescription(changelog);
|
||||
@@ -150,6 +152,16 @@ public class GitlabReleaser implements Releaser {
|
||||
// remote tag/release
|
||||
api.createRelease(gitlab.getOwner(), gitlab.getName(), release);
|
||||
api.linkAssets(gitlab.getOwner(), gitlab.getName(), release, uploads);
|
||||
|
||||
Optional<Milestone> milestone = api.findMilestoneByName(
|
||||
gitlab.getOwner(),
|
||||
gitlab.getName(),
|
||||
gitlab.getMilestone().getEffectiveName());
|
||||
if (milestone.isPresent()) {
|
||||
api.closeMilestone(gitlab.getOwner(),
|
||||
gitlab.getName(),
|
||||
milestone.get());
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteTags(Gitlab api, String owner, String repo, String tagName) {
|
||||
|
||||
@@ -61,4 +61,11 @@ public interface GitlabAPI {
|
||||
@RequestLine("POST /projects/{projectId}/releases/{tagName}/assets/links")
|
||||
@Headers("Content-Type: multipart/form-data")
|
||||
Link linkAsset(LinkRequest link, @Param("projectId") Integer projectId, @Param("tagName") String tagName);
|
||||
|
||||
@RequestLine("GET /projects/{projectId}/milestones")
|
||||
List<Milestone> findMilestoneByTitle(@Param("projectId") Integer projectId, @QueryMap Map<String, Object> queryMap);
|
||||
|
||||
@RequestLine("PUT /projects/{projectId}/milestones/{milestoneId}")
|
||||
@Headers("Content-Type: application/json")
|
||||
void updateMilestone(Map<String, Object> params, @Param("projectId") Integer projectId, @Param("milestoneId") Integer milestoneId);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Copyright 2020-2021 Andres Almiray.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jreleaser.sdk.gitlab.api;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class Milestone {
|
||||
private Integer id;
|
||||
private Integer iid;
|
||||
private Integer projectId;
|
||||
private String title;
|
||||
private String description;
|
||||
private String state;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getIid() {
|
||||
return iid;
|
||||
}
|
||||
|
||||
public void setIid(Integer iid) {
|
||||
this.iid = iid;
|
||||
}
|
||||
|
||||
public Integer getProjectId() {
|
||||
return projectId;
|
||||
}
|
||||
|
||||
public void setProjectId(Integer projectId) {
|
||||
this.projectId = projectId;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getState() {
|
||||
return state;
|
||||
}
|
||||
|
||||
public void setState(String state) {
|
||||
this.state = state;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user