mirror of
https://github.com/jlengrand/jreleaser.git
synced 2026-03-10 08:31:24 +00:00
[release] add support for Gitea. Fixes #10
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
package org.jreleaser.engine.release;
|
||||
|
||||
import org.jreleaser.model.Gitea;
|
||||
import org.jreleaser.model.Github;
|
||||
import org.jreleaser.model.Gitlab;
|
||||
import org.jreleaser.model.JReleaserContext;
|
||||
@@ -57,6 +58,9 @@ public class Releasers {
|
||||
if (null != context.getModel().getRelease().getGitlab()) {
|
||||
return (RB) builders.get(Gitlab.NAME);
|
||||
}
|
||||
if (null != context.getModel().getRelease().getGitea()) {
|
||||
return (RB) builders.get(Gitea.NAME);
|
||||
}
|
||||
|
||||
throw new JReleaserException("No suitable git releaser has been configured");
|
||||
}
|
||||
|
||||
@@ -32,7 +32,6 @@ public class Gitea extends GitService {
|
||||
|
||||
public Gitea() {
|
||||
super(NAME);
|
||||
setHost("try.gitea.io");
|
||||
setRepoUrlFormat("https://{{repoHost}}/{{repoOwner}}/{{repoName}}");
|
||||
setCommitUrlFormat("https://{{repoHost}}/{{repoOwner}}/{{repoName}}/commits");
|
||||
setDownloadUrlFormat("https://{{repoHost}}/{{repoOwner}}/{{repoName}}/releases/download/{{tagName}}/{{artifactFileName}}");
|
||||
|
||||
@@ -34,6 +34,10 @@ public abstract class GiteaValidator extends GitServiceValidator {
|
||||
|
||||
validateGitService(context, gitea, errors);
|
||||
|
||||
if (isBlank(gitea.getApiEndpoint())) {
|
||||
errors.add("gitea.apiEndpoint must not be blank");
|
||||
}
|
||||
|
||||
if (isBlank(gitea.getTargetCommitish())) {
|
||||
gitea.setTargetCommitish("main");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ dependencies {
|
||||
// release
|
||||
api project(':github-java-sdk')
|
||||
api project(':gitlab-java-sdk')
|
||||
api project(':gitea-java-sdk')
|
||||
// tools
|
||||
api project(':jreleaser-tools')
|
||||
}
|
||||
@@ -30,6 +30,7 @@ asmVersion = 8.0.1
|
||||
awaitilityVersion = 4.0.3
|
||||
bouncyCastleVersion = 1.68
|
||||
feignVersion = 10.12
|
||||
feignFormVersion = 3.8.0
|
||||
githubVersion = 1.125
|
||||
greenmailVersion = 1.6.3
|
||||
guavaVersion = 30.1-jre
|
||||
|
||||
@@ -25,7 +25,7 @@ import org.eclipse.jgit.lib.Ref;
|
||||
import org.eclipse.jgit.revwalk.RevCommit;
|
||||
import org.jreleaser.model.Changelog;
|
||||
import org.jreleaser.model.GitService;
|
||||
import org.jreleaser.model.Github;
|
||||
import org.jreleaser.model.Gitlab;
|
||||
import org.jreleaser.model.JReleaserContext;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -37,7 +37,6 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static org.jreleaser.sdk.git.GitSdk.extractTagName;
|
||||
import static org.jreleaser.util.StringUtils.isNotBlank;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
@@ -58,7 +57,7 @@ public class ChangelogGenerator {
|
||||
String commitsUrl = gitService.getResolvedCommitUrl(context.getModel().getProject());
|
||||
|
||||
String separator = System.lineSeparator();
|
||||
if (!Github.NAME.equals(gitService.getServiceName())) {
|
||||
if (Gitlab.NAME.equals(gitService.getServiceName())) {
|
||||
separator += System.lineSeparator();
|
||||
}
|
||||
String commitSeparator = separator;
|
||||
@@ -92,16 +91,11 @@ public class ChangelogGenerator {
|
||||
String[] input = commit.getFullMessage().trim().split(System.lineSeparator());
|
||||
|
||||
List<String> lines = new ArrayList<>();
|
||||
for (int i = 0; i < input.length; i++) {
|
||||
if (i == 0) {
|
||||
if (changelog.isLinks()) {
|
||||
lines.add("[" + abbreviation + "](" + commitsUrl + "/" + commitHash + ") " + input[i].trim());
|
||||
} else {
|
||||
lines.add(abbreviation + " " + input[i].trim());
|
||||
}
|
||||
} else if (isNotBlank(input[i])) {
|
||||
lines.add(" " + input[i].trim());
|
||||
}
|
||||
|
||||
if (changelog.isLinks()) {
|
||||
lines.add("[" + abbreviation + "](" + commitsUrl + "/" + commitHash + ") " + input[0].trim());
|
||||
} else {
|
||||
lines.add(abbreviation + " " + input[0].trim());
|
||||
}
|
||||
|
||||
return String.join(commitSeparator, lines);
|
||||
|
||||
34
sdks/gitea-java-sdk/gitea-java-sdk.gradle
Normal file
34
sdks/gitea-java-sdk/gitea-java-sdk.gradle
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
dependencies {
|
||||
compileOnly "org.kordamp.jipsy:jipsy-annotations:${jipsyVersion}"
|
||||
annotationProcessor "org.kordamp.jipsy:jipsy-processor:${jipsyVersion}"
|
||||
|
||||
api project(':jreleaser-model')
|
||||
api project(':git-sdk')
|
||||
|
||||
api "org.apache.tika:tika-core:$tikaVersion"
|
||||
|
||||
api "io.github.openfeign:feign-core:$feignVersion"
|
||||
api "io.github.openfeign:feign-jackson:$feignVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
api "io.github.openfeign.form:feign-form:$feignFormVersion"
|
||||
|
||||
testImplementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"
|
||||
}
|
||||
19
sdks/gitea-java-sdk/gradle.properties
Normal file
19
sdks/gitea-java-sdk/gradle.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
project_description = Java SDK for Gitea
|
||||
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import feign.Feign;
|
||||
import feign.Request;
|
||||
import feign.form.FormData;
|
||||
import feign.form.FormEncoder;
|
||||
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.GtOrganization;
|
||||
import org.jreleaser.sdk.gitea.api.GtRelease;
|
||||
import org.jreleaser.sdk.gitea.api.GtRepository;
|
||||
import org.jreleaser.util.CollectionUtils;
|
||||
import org.jreleaser.util.JReleaserLogger;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
class Gitea {
|
||||
private static final String API_V1 = "/api/v1";
|
||||
private final Tika tika = new Tika();
|
||||
|
||||
private final JReleaserLogger logger;
|
||||
private final GiteaAPI api;
|
||||
|
||||
Gitea(JReleaserLogger logger, String endpoint, String token) throws IOException {
|
||||
requireNonNull(logger, "'logger' must not be blank");
|
||||
requireNonBlank(token, "'token' must not be blank");
|
||||
requireNonBlank(endpoint, "'endpoint' must not be blank");
|
||||
|
||||
if (!endpoint.endsWith(API_V1)) {
|
||||
if (endpoint.endsWith("/")) {
|
||||
endpoint = endpoint.substring(0, endpoint.length() - 1);
|
||||
}
|
||||
endpoint += API_V1;
|
||||
}
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
.setSerializationInclusion(JsonInclude.Include.NON_NULL)
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
|
||||
.configure(SerializationFeature.INDENT_OUTPUT, true);
|
||||
|
||||
this.logger = logger;
|
||||
this.api = Feign.builder()
|
||||
.encoder(new FormEncoder(new JacksonEncoder(objectMapper)))
|
||||
.decoder(new JacksonDecoder(objectMapper))
|
||||
.requestInterceptor(template -> template.header("Authorization", String.format("token %s", token)))
|
||||
.errorDecoder((methodKey, response) -> new GiteaAPIException(response.status(), response.reason(), response.headers()))
|
||||
.options(new Request.Options(20, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true))
|
||||
.target(GiteaAPI.class, endpoint);
|
||||
}
|
||||
|
||||
GtRepository findRepository(String owner, String repo) {
|
||||
logger.debug("Lookup repository {}/{}", owner, repo);
|
||||
try {
|
||||
return api.getRepository(owner, repo);
|
||||
} catch (GiteaAPIException e) {
|
||||
if (e.isNotFound()) {
|
||||
// ok
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
GtRepository createRepository(String owner, String repo) {
|
||||
logger.debug("Creating repository {}/{}", owner, repo);
|
||||
|
||||
Map<String, Object> params = CollectionUtils.<String, Object>map()
|
||||
.e("name", repo)
|
||||
.e("private", false);
|
||||
|
||||
GtOrganization organization = resolveOrganization(owner);
|
||||
if (null != organization) {
|
||||
return api.createRepository(params, owner);
|
||||
}
|
||||
|
||||
return api.createRepository(params);
|
||||
}
|
||||
|
||||
private GtOrganization resolveOrganization(String name) {
|
||||
try {
|
||||
return api.getOrganization(name);
|
||||
} catch (GiteaAPIException e) {
|
||||
if (e.isNotFound()) {
|
||||
// ok
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
GtRelease findReleaseByTag(String owner, String repo, String tagName) {
|
||||
logger.debug("Fetching release on {}/{} with tag {}", owner, repo, tagName);
|
||||
|
||||
try {
|
||||
return api.getReleaseByTagName(owner, repo, tagName);
|
||||
} catch (GiteaAPIException e) {
|
||||
if (e.isNotFound()) {
|
||||
// ok
|
||||
return null;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteRelease(String owner, String repo, String tagName, Integer id) throws GiteaAPIException {
|
||||
logger.debug("Deleting release {} from {}/{} ({})", tagName, owner, repo, id);
|
||||
|
||||
try {
|
||||
api.deleteRelease(owner, repo, id);
|
||||
} catch (GiteaAPIException e) {
|
||||
if (e.isNotFound()) {
|
||||
// OK. Release might have been deleted but
|
||||
// tag still exists.
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
void deleteTag(String owner, String repo, String tagName) throws GiteaAPIException {
|
||||
logger.debug("Deleting tag {} from {}/{}", tagName, owner, repo);
|
||||
|
||||
api.deleteTag(owner, repo, tagName);
|
||||
}
|
||||
|
||||
GtRelease createRelease(String owner, String repo, GtRelease release) throws GiteaAPIException {
|
||||
logger.debug("Creating release on {}/{} with tag {}", owner, repo, release.getTagName());
|
||||
|
||||
return api.createRelease(release, owner, repo);
|
||||
}
|
||||
|
||||
void uploadAssets(String owner, String repo, GtRelease release, List<Path> assets) throws IOException {
|
||||
for (Path asset : assets) {
|
||||
if (0 == asset.toFile().length() || !Files.exists(asset)) {
|
||||
// do not upload empty or non existent files
|
||||
continue;
|
||||
}
|
||||
|
||||
logger.info(" - Uploading {}", asset.getFileName().toString());
|
||||
try {
|
||||
api.uploadAsset(owner, repo, release.getId(), toFormData(asset));
|
||||
} catch (GiteaAPIException e) {
|
||||
logger.error(" x Failed to upload {}", asset.getFileName());
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FormData toFormData(Path asset) throws IOException {
|
||||
return FormData.builder()
|
||||
.fileName(asset.getFileName().toString())
|
||||
.contentType(MediaType.parse(tika.detect(asset)).toString())
|
||||
.data(Files.readAllBytes(asset))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class GiteaException extends RuntimeException {
|
||||
public GiteaException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public GiteaException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public GiteaException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jreleaser.model.JReleaserContext;
|
||||
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.jreleaser.sdk.gitea.api.GiteaAPIException;
|
||||
import org.jreleaser.sdk.gitea.api.GtRelease;
|
||||
import org.jreleaser.sdk.gitea.api.GtRepository;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class GiteaReleaser implements Releaser {
|
||||
private final JReleaserContext context;
|
||||
private final List<Path> assets = new ArrayList<>();
|
||||
|
||||
GiteaReleaser(JReleaserContext context, List<Path> assets) {
|
||||
this.context = context;
|
||||
this.assets.addAll(assets);
|
||||
}
|
||||
|
||||
public void release() throws ReleaseException {
|
||||
org.jreleaser.model.Gitea gitea = context.getModel().getRelease().getGitea();
|
||||
context.getLogger().info("Releasing to {}", gitea.getResolvedRepoUrl(context.getModel().getProject()));
|
||||
String tagName = gitea.getEffectiveTagName(context.getModel().getProject());
|
||||
|
||||
try {
|
||||
String changelog = context.getChangelog();
|
||||
|
||||
Gitea api = new Gitea(context.getLogger(), gitea.getApiEndpoint(), gitea.getResolvedToken());
|
||||
|
||||
context.getLogger().debug("Looking up release with tag {} at repository {}", tagName, gitea.getCanonicalRepoName());
|
||||
GtRelease release = api.findReleaseByTag(gitea.getOwner(), gitea.getName(), tagName);
|
||||
if (null != release) {
|
||||
context.getLogger().debug("Release {} exists", tagName);
|
||||
if (gitea.isOverwrite()) {
|
||||
context.getLogger().debug("Deleting release {}", tagName);
|
||||
if (!context.isDryrun()) {
|
||||
api.deleteRelease(gitea.getOwner(), gitea.getName(), tagName, release.getId());
|
||||
}
|
||||
context.getLogger().debug("Creating release {}", tagName);
|
||||
createRelease(api, tagName, changelog, context.getModel().getProject().isSnapshot());
|
||||
} else if (gitea.isAllowUploadToExisting()) {
|
||||
context.getLogger().debug("Updating release {}", tagName);
|
||||
if (!context.isDryrun()) {
|
||||
api.uploadAssets(gitea.getOwner(), gitea.getName(), release, assets);
|
||||
}
|
||||
} else {
|
||||
throw new IllegalStateException("Gitea release failed because release " +
|
||||
tagName + " already exists. overwrite = false; allowUploadToExisting = false");
|
||||
}
|
||||
} else {
|
||||
context.getLogger().debug("Release {} does not exist", tagName);
|
||||
context.getLogger().debug("Creating release {}", tagName);
|
||||
createRelease(api, tagName, changelog, context.getModel().getProject().isSnapshot());
|
||||
}
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
throw new ReleaseException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Repository maybeCreateRepository(String owner, String repo, String password) throws IOException {
|
||||
org.jreleaser.model.Gitea gitea = context.getModel().getRelease().getGitea();
|
||||
context.getLogger().debug("Looking up {}/{}", owner, repo);
|
||||
|
||||
Gitea api = new Gitea(context.getLogger(), gitea.getApiEndpoint(), password);
|
||||
GtRepository repository = api.findRepository(owner, repo);
|
||||
if (null == repository) {
|
||||
repository = api.createRepository(owner, repo);
|
||||
}
|
||||
|
||||
return new Repository(
|
||||
owner,
|
||||
repo,
|
||||
repository.getHtmlUrl(),
|
||||
repository.getCloneUrl());
|
||||
}
|
||||
|
||||
private void createRelease(Gitea api, String tagName, String changelog, boolean deleteTags) throws IOException {
|
||||
org.jreleaser.model.Gitea gitea = context.getModel().getRelease().getGitea();
|
||||
|
||||
if (context.isDryrun()) {
|
||||
for (Path asset : assets) {
|
||||
if (0 == asset.toFile().length() || !Files.exists(asset)) {
|
||||
// do not upload empty or non existent files
|
||||
continue;
|
||||
}
|
||||
|
||||
context.getLogger().debug(" - Uploading asset {}", asset.getFileName().toString());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (deleteTags) {
|
||||
deleteTags(api, gitea.getOwner(), gitea.getName(), tagName);
|
||||
}
|
||||
|
||||
// local tag
|
||||
if (deleteTags || !context.getModel().getRelease().getGitService().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.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);
|
||||
}
|
||||
|
||||
private void deleteTags(Gitea api, String owner, String repo, String tagName) {
|
||||
// delete remote tag
|
||||
try {
|
||||
api.deleteTag(owner, repo, tagName);
|
||||
} catch (GiteaAPIException ignored) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.sdk.gitea;
|
||||
|
||||
import org.jreleaser.model.releaser.spi.AbstractReleaserBuilder;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class GiteaReleaserBuilder extends AbstractReleaserBuilder<GiteaReleaser> {
|
||||
@Override
|
||||
public GiteaReleaser build() {
|
||||
validate();
|
||||
|
||||
return new GiteaReleaser(context, assets);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import org.jreleaser.model.releaser.spi.ReleaserBuilderFactory;
|
||||
import org.kordamp.jipsy.annotations.ServiceProviderFor;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@ServiceProviderFor(ReleaserBuilderFactory.class)
|
||||
public class GiteaReleaserBuilderFactory implements ReleaserBuilderFactory<GiteaReleaser, GiteaReleaserBuilder> {
|
||||
@Override
|
||||
public String getName() {
|
||||
return org.jreleaser.model.Gitea.NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GiteaReleaserBuilder getBuilder() {
|
||||
return new GiteaReleaserBuilder();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 feign.Headers;
|
||||
import feign.Param;
|
||||
import feign.RequestLine;
|
||||
import feign.form.FormData;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public interface GiteaAPI {
|
||||
@RequestLine("GET /repos/{owner}/{repo}")
|
||||
GtRepository getRepository(@Param("owner") String owner, @Param("repo") String repo);
|
||||
|
||||
@RequestLine("GET /orgs/{org}")
|
||||
GtOrganization getOrganization(@Param("org") String org);
|
||||
|
||||
@RequestLine("POST /orgs/{org}/repos")
|
||||
@Headers("Content-Type: application/json")
|
||||
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);
|
||||
|
||||
@RequestLine("GET /repos/{owner}/{repo}/releases/tags/{tag}")
|
||||
GtRelease getReleaseByTagName(@Param("owner") String owner, @Param("repo") String repo, @Param("tag") String tag);
|
||||
|
||||
@RequestLine("DELETE /repos/{owner}/{repo}/releases/{id}")
|
||||
void deleteRelease(@Param("owner") String owner, @Param("repo") String repo, @Param("id") Integer id);
|
||||
|
||||
@RequestLine("DELETE /repos/{owner}/{repo}/releases/tags/{tag}")
|
||||
void deleteTag(@Param("owner") String owner, @Param("repo") String repo, @Param("tag") String tag);
|
||||
|
||||
@RequestLine("POST /repos/{owner}/{repo}/releases")
|
||||
@Headers("Content-Type: application/json")
|
||||
GtRelease createRelease(GtRelease release, @Param("owner") String owner, @Param("repo") String repo);
|
||||
|
||||
@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);
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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 java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
public class GiteaAPIException extends RuntimeException {
|
||||
private final int status;
|
||||
private final String reason;
|
||||
private final Map<String, Collection<String>> headers;
|
||||
|
||||
public GiteaAPIException(int status, String reason) {
|
||||
this(status, reason, Collections.emptyMap());
|
||||
}
|
||||
|
||||
public GiteaAPIException(int status, String reason, Map<String, Collection<String>> headers) {
|
||||
this.status = status;
|
||||
this.reason = reason;
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
public int getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public String getReason() {
|
||||
return reason;
|
||||
}
|
||||
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return headers;
|
||||
}
|
||||
|
||||
public boolean isNotFound() {
|
||||
return 404 == status;
|
||||
}
|
||||
|
||||
public boolean isForbidden() {
|
||||
return 403 == status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 GtAttachment {
|
||||
private String browserDownloadUrl;
|
||||
private Integer id;
|
||||
private String name;
|
||||
private Integer size;
|
||||
private String uuid;
|
||||
|
||||
public String getBrowserDownloadUrl() {
|
||||
return browserDownloadUrl;
|
||||
}
|
||||
|
||||
public void setBrowserDownloadUrl(String browserDownloadUrl) {
|
||||
this.browserDownloadUrl = browserDownloadUrl;
|
||||
}
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Integer getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Integer size) {
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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 GtOrganization {
|
||||
private Integer id;
|
||||
private String username;
|
||||
private String fullName;
|
||||
private String description;
|
||||
private String website;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getWebsite() {
|
||||
return website;
|
||||
}
|
||||
|
||||
public void setWebsite(String website) {
|
||||
this.website = website;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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 GtRelease {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String htmlUrl;
|
||||
private String tagName;
|
||||
private String url;
|
||||
private String body;
|
||||
private boolean prerelease;
|
||||
private String targetCommitish;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return htmlUrl;
|
||||
}
|
||||
|
||||
public void setHtmlUrl(String htmlUrl) {
|
||||
this.htmlUrl = htmlUrl;
|
||||
}
|
||||
|
||||
public String getTagName() {
|
||||
return tagName;
|
||||
}
|
||||
|
||||
public void setTagName(String tagName) {
|
||||
this.tagName = tagName;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getBody() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void setBody(String body) {
|
||||
this.body = body;
|
||||
}
|
||||
|
||||
public boolean isPrerelease() {
|
||||
return prerelease;
|
||||
}
|
||||
|
||||
public void setPrerelease(boolean prerelease) {
|
||||
this.prerelease = prerelease;
|
||||
}
|
||||
|
||||
public String getTargetCommitish() {
|
||||
return targetCommitish;
|
||||
}
|
||||
|
||||
public void setTargetCommitish(String targetCommitish) {
|
||||
this.targetCommitish = targetCommitish;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* @author Andres Almiray
|
||||
* @since 0.1.0
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class GtRepository {
|
||||
private Integer id;
|
||||
private String name;
|
||||
private String fullName;
|
||||
private String htmlUrl;
|
||||
private String cloneUrl;
|
||||
|
||||
public Integer getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Integer id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getFullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public void setFullName(String fullName) {
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String getHtmlUrl() {
|
||||
return htmlUrl;
|
||||
}
|
||||
|
||||
public void setHtmlUrl(String htmlUrl) {
|
||||
this.htmlUrl = htmlUrl;
|
||||
}
|
||||
|
||||
public String getCloneUrl() {
|
||||
return cloneUrl;
|
||||
}
|
||||
|
||||
public void setCloneUrl(String cloneUrl) {
|
||||
this.cloneUrl = cloneUrl;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ dependencies {
|
||||
api "io.github.openfeign:feign-jackson:$feignVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
api 'io.github.openfeign.form:feign-form:3.8.0'
|
||||
api "io.github.openfeign.form:feign-form:$feignFormVersion"
|
||||
|
||||
testImplementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"
|
||||
}
|
||||
@@ -57,7 +57,7 @@ import static org.jreleaser.util.StringUtils.requireNonBlank;
|
||||
*/
|
||||
class Gitlab {
|
||||
static final String ENDPOINT = "https://gitlab.com/api/v4";
|
||||
private static final String API_V_4 = "/api/v4";
|
||||
private static final String API_V4 = "/api/v4";
|
||||
private final Tika tika = new Tika();
|
||||
|
||||
private final JReleaserLogger logger;
|
||||
@@ -75,14 +75,14 @@ class Gitlab {
|
||||
endpoint = ENDPOINT;
|
||||
}
|
||||
|
||||
if (!endpoint.endsWith(API_V_4)) {
|
||||
if (!endpoint.endsWith(API_V4)) {
|
||||
if (endpoint.endsWith("/")) {
|
||||
endpoint = endpoint.substring(0, endpoint.length() - 1);
|
||||
}
|
||||
endpoint += API_V_4;
|
||||
endpoint += API_V4;
|
||||
}
|
||||
|
||||
apiHost = endpoint.substring(0, endpoint.length() - API_V_4.length());
|
||||
apiHost = endpoint.substring(0, endpoint.length() - API_V4.length());
|
||||
|
||||
ObjectMapper objectMapper = new ObjectMapper()
|
||||
.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE)
|
||||
@@ -233,7 +233,7 @@ class Gitlab {
|
||||
private FormData toFormData(Path asset) throws IOException {
|
||||
return FormData.builder()
|
||||
.fileName(asset.getFileName().toString())
|
||||
.contentType(MediaType.parse(new Tika().detect(asset)).toString())
|
||||
.contentType(MediaType.parse(tika.detect(asset)).toString())
|
||||
.data(Files.readAllBytes(asset))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -139,7 +139,6 @@ public class GitlabReleaser implements Releaser {
|
||||
GitSdk.of(context).tag(tagName, true);
|
||||
}
|
||||
|
||||
|
||||
List<FileUpload> uploads = api.uploadAssets(gitlab.getOwner(), gitlab.getName(), assets);
|
||||
|
||||
Release release = new Release();
|
||||
|
||||
@@ -25,7 +25,7 @@ dependencies {
|
||||
api "io.github.openfeign:feign-jackson:$feignVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
api 'io.github.openfeign.form:feign-form:3.8.0'
|
||||
api "io.github.openfeign.form:feign-form:$feignFormVersion"
|
||||
|
||||
testImplementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"
|
||||
}
|
||||
@@ -25,7 +25,7 @@ dependencies {
|
||||
api "io.github.openfeign:feign-jackson:$feignVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-core:$jacksonVersion"
|
||||
api "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion"
|
||||
api 'io.github.openfeign.form:feign-form:3.8.0'
|
||||
api "io.github.openfeign.form:feign-form:$feignFormVersion"
|
||||
|
||||
testImplementation "com.github.tomakehurst:wiremock-jre8:$wiremockVersion"
|
||||
}
|
||||
Reference in New Issue
Block a user