<commit_before>package org.jenkinsci.plugins.githubreleaseperformer;

import hudson.Extension;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.tokenmacro.TokenMacro;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHReleaseBuilder;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

import java.io.*;

public class GitHubReleasePerformer extends Builder {

	private final String apiUrl;
	private final String tag;
	private final String branch;
	private final String releaseNotesFile;
	private final String user;
	private final String password;
	private final String owner;
	private final String repository;

	private GitHub github;
	private GHRepository ghRepository;

	private static final String RELEASE_NOTES_SEPARATOR = "###################";

	private static final String RELEASE_NOTES_TEMPLATE =
			"### New features\n\n* [JIRA-TICKET](jira-link): Some feature\n\n### Improvements\n\n* [JIRA-TICKET](jira-link): Some improvement\n\n### Bug fixes\n\n* [JIRA-TICKET](jira-link): Some bug fix";

	@SuppressWarnings("unused")
	@DataBoundConstructor
	public GitHubReleasePerformer(String apiUrl, String user, String password, String tag, String branch, String releaseNotesFile,
			String owner,
			String repository) {
		this.apiUrl = apiUrl;
		this.tag = Util.fixEmptyAndTrim(tag);
		this.branch = Util.fixEmptyAndTrim(branch);
		this.releaseNotesFile = Util.fixEmptyAndTrim(releaseNotesFile);
		this.user = user;
		this.password = password;
		this.owner = Util.fixEmptyAndTrim(owner);
		this.repository = Util.fixEmptyAndTrim(repository);
	}

	@Override
	public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
			BuildListener listener) {
		String resolvedUser = user;
		String resolvedPassword = password;
		String resolvedRepository = repository;
		String resolvedOwner = owner;
		String resolvedTag = tag;
		String resolvedBranch = branch;
		String resolvedReleaseNotesFile = releaseNotesFile;
		try {
			resolvedUser = TokenMacro.expandAll(build, listener, user);
			resolvedPassword = TokenMacro.expandAll(build, listener, password);
			resolvedRepository = TokenMacro.expandAll(build, listener, repository);
			resolvedOwner = TokenMacro.expandAll(build, listener, owner);
			resolvedTag = TokenMacro.expandAll(build, listener, tag);
			resolvedBranch = TokenMacro.expandAll(build, listener, branch);
			resolvedReleaseNotesFile = TokenMacro.expandAll(build, listener, releaseNotesFile);
		} catch (Exception e) {
			listener.error("Unable to resolve macro [%s]", e.getMessage());
		}
		try {
			if (apiUrl != null && !apiUrl.isEmpty()) {
				github = GitHub.connectToEnterprise(apiUrl, resolvedUser, resolvedPassword);
			} else {
				github = GitHub.connectUsingPassword(resolvedUser, resolvedPassword);
			}
			ghRepository = github.getRepository(resolvedOwner + "/" + resolvedRepository);
			GHContent currentReleaseNotes = getReleaseNotesFile(resolvedReleaseNotesFile, resolvedBranch, listener);
			boolean result =
					createRelease(currentReleaseNotes, resolvedTag, resolvedReleaseNotesFile, resolvedBranch, listener);
			if (result) {
				writeNewReleaseNotes(currentReleaseNotes, resolvedTag, resolvedReleaseNotesFile, resolvedBranch, listener);
			}
		} catch (IOException e) {
			listener.error("Unable to connect to repository [%s], [%s]", apiUrl + "/" + resolvedOwner + "/" + resolvedRepository,
					e.getMessage());
		}

		// Release must not fail if GitHub release fails
		return true;
	}

	private GHContent getReleaseNotesFile(String releaseNotesFile, String branch, BuildListener listener) {
		GHContent result = null;
		try {
			result = ghRepository.getFileContent(releaseNotesFile, branch);
		} catch (IOException e) {
			listener.error("Unable to find file [%s], [%s]", releaseNotesFile, e.getMessage());
		}
		return result;
	}

	private boolean createRelease(GHContent releaseNotes, String tag, String releaseNotesFile, String branch,
			BuildListener listener) {
		boolean result = true;
		StringBuilder stringBuilder = null;
		boolean separatorFound = false;
		if (releaseNotes != null) {
			try {
				InputStream inputStream = releaseNotes.read();
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

				stringBuilder = new StringBuilder();
				String line;
				separatorFound = false;
				while ((line = bufferedReader.readLine()) != null) {
					if (line.trim().equals(RELEASE_NOTES_SEPARATOR) || line.trim().matches("^###[#]+$")) {
						separatorFound = true;
						break;
					}
					stringBuilder.append(line).append("\n");
				}
			} catch (IOException e) {
				listener.error("Unable to read release notes, [%s]", e.getMessage());
			}
		}

		GHReleaseBuilder releaseBuilder = new GHReleaseBuilder(ghRepository, tag);
		if (stringBuilder != null && separatorFound) {
			releaseBuilder.body(stringBuilder.toString());
		}
		releaseBuilder.commitish(branch);
		releaseBuilder.draft(false);
		releaseBuilder.name(tag);
		releaseBuilder.prerelease(false);
		try {
			releaseBuilder.create();
			String message = String.format("Release created successfully [%s]", tag);
			listener.getLogger().println(message);
		} catch (IOException e) {
			listener.error("Unable to create release, [%s]", e.getMessage());
			result = false;
		}
		return result;
	}

	private void writeNewReleaseNotes(GHContent currentReleaseNotes, String tag, String releaseNotesFile, String branch,
			BuildListener listener) {
		if (currentReleaseNotes != null) {
			try {
				InputStream inputStream = currentReleaseNotes.read();
				StringWriter writer = new StringWriter();
				IOUtils.copy(inputStream, writer, "UTF-8");
				StringBuilder stringBuilder = new StringBuilder(RELEASE_NOTES_TEMPLATE);
				stringBuilder.append("\n\n");
				stringBuilder.append(RELEASE_NOTES_SEPARATOR);
				stringBuilder.append("\n\n");
				stringBuilder.append(writer.toString());

				currentReleaseNotes
						.update(stringBuilder.toString(), String.format("Updating %s after release %s", releaseNotesFile, tag),
								branch);
			} catch (IOException e) {
				listener.error("Unable to update release note file [%s], [%s]", releaseNotesFile, e.getMessage());
			}

		} else {
			try {
				ghRepository.createContent(RELEASE_NOTES_TEMPLATE + "\n" + RELEASE_NOTES_SEPARATOR + "\n",
						String.format("Updating %s after release %s", releaseNotesFile, tag),
						releaseNotesFile, branch);
			} catch (IOException e) {
				listener.error("Unable to create release note file [%s], [%s]", releaseNotesFile, e.getMessage());
			}
		}
	}

	@SuppressWarnings("unused")<commit_msg>implement Ilia's logic 2<commit_after>package org.jenkinsci.plugins.githubreleaseperformer;

import hudson.Extension;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.tasks.BuildStepDescriptor;
import hudson.tasks.Builder;
import net.sf.json.JSONObject;
import org.apache.commons.io.IOUtils;
import org.jenkinsci.plugins.tokenmacro.TokenMacro;
import org.kohsuke.github.GHContent;
import org.kohsuke.github.GHReleaseBuilder;
import org.kohsuke.github.GHRepository;
import org.kohsuke.github.GitHub;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

import java.io.*;

public class GitHubReleasePerformer extends Builder {

	private final String apiUrl;
	private final String tag;
	private final String branch;
	private final String releaseNotesFile;
	private final String user;
	private final String password;
	private final String owner;
	private final String repository;

	private GitHub github;
	private GHRepository ghRepository;

	private static final String RELEASE_NOTES_SEPARATOR = "###################";

	private static final String RELEASE_NOTES_TEMPLATE =
			"Next release\n============\n\n### New features\n\n* [JIRA-TICKET](jira-link): Some feature\n\n### Improvements\n\n* [JIRA-TICKET](jira-link): Some improvement\n\n### Bug fixes\n\n* [JIRA-TICKET](jira-link): Some bug fix";

	@SuppressWarnings("unused")
	@DataBoundConstructor
	public GitHubReleasePerformer(String apiUrl, String user, String password, String tag, String branch, String releaseNotesFile,
			String owner,
			String repository) {
		this.apiUrl = apiUrl;
		this.tag = Util.fixEmptyAndTrim(tag);
		this.branch = Util.fixEmptyAndTrim(branch);
		this.releaseNotesFile = Util.fixEmptyAndTrim(releaseNotesFile);
		this.user = user;
		this.password = password;
		this.owner = Util.fixEmptyAndTrim(owner);
		this.repository = Util.fixEmptyAndTrim(repository);
	}

	@Override
	public boolean perform(AbstractBuild<?, ?> build, Launcher launcher,
			BuildListener listener) {
		String resolvedUser = user;
		String resolvedPassword = password;
		String resolvedRepository = repository;
		String resolvedOwner = owner;
		String resolvedTag = tag;
		String resolvedBranch = branch;
		String resolvedReleaseNotesFile = releaseNotesFile;
		try {
			resolvedUser = TokenMacro.expandAll(build, listener, user);
			resolvedPassword = TokenMacro.expandAll(build, listener, password);
			resolvedRepository = TokenMacro.expandAll(build, listener, repository);
			resolvedOwner = TokenMacro.expandAll(build, listener, owner);
			resolvedTag = TokenMacro.expandAll(build, listener, tag);
			resolvedBranch = TokenMacro.expandAll(build, listener, branch);
			resolvedReleaseNotesFile = TokenMacro.expandAll(build, listener, releaseNotesFile);
		} catch (Exception e) {
			listener.error("Unable to resolve macro [%s]", e.getMessage());
		}
		try {
			if (apiUrl != null && !apiUrl.isEmpty()) {
				github = GitHub.connectToEnterprise(apiUrl, resolvedUser, resolvedPassword);
			} else {
				github = GitHub.connectUsingPassword(resolvedUser, resolvedPassword);
			}
			ghRepository = github.getRepository(resolvedOwner + "/" + resolvedRepository);
			GHContent currentReleaseNotes = getReleaseNotesFile(resolvedReleaseNotesFile, resolvedBranch, listener);
			boolean result =
					createRelease(currentReleaseNotes, resolvedTag, resolvedReleaseNotesFile, resolvedBranch, listener);
			if (result) {
				writeNewReleaseNotes(currentReleaseNotes, resolvedTag, resolvedReleaseNotesFile, resolvedBranch, listener);
			}
		} catch (IOException e) {
			listener.error("Unable to connect to repository [%s], [%s]", apiUrl + "/" + resolvedOwner + "/" + resolvedRepository,
					e.getMessage());
		}

		// Release must not fail if GitHub release fails
		return true;
	}

	private GHContent getReleaseNotesFile(String releaseNotesFile, String branch, BuildListener listener) {
		GHContent result = null;
		try {
			result = ghRepository.getFileContent(releaseNotesFile, branch);
		} catch (IOException e) {
			listener.error("Unable to find file [%s], [%s]", releaseNotesFile, e.getMessage());
		}
		return result;
	}

	private boolean createRelease(GHContent releaseNotes, String tag, String releaseNotesFile, String branch,
			BuildListener listener) {
		boolean result = true;
		StringBuilder stringBuilder = null;
		boolean separatorFound = false;
		if (releaseNotes != null) {
			try {
				InputStream inputStream = releaseNotes.read();
				BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));

				stringBuilder = new StringBuilder();
				String line;
				separatorFound = false;
				while ((line = bufferedReader.readLine()) != null) {
					if (line.trim().equals(RELEASE_NOTES_SEPARATOR) || line.trim().matches("^###[#]+$")) {
						separatorFound = true;
						break;
					}
					stringBuilder.append(line).append("\n");
				}
			} catch (IOException e) {
				listener.error("Unable to read release notes, [%s]", e.getMessage());
			}
		}

		GHReleaseBuilder releaseBuilder = new GHReleaseBuilder(ghRepository, tag);
		if (stringBuilder != null && separatorFound) {
			releaseBuilder.body(stringBuilder.toString().replace("Next release", tag));
		}
		releaseBuilder.commitish(branch);
		releaseBuilder.draft(false);
		releaseBuilder.name(tag);
		releaseBuilder.prerelease(false);
		try {
			releaseBuilder.create();
			String message = String.format("Release created successfully [%s]", tag);
			listener.getLogger().println(message);
		} catch (IOException e) {
			listener.error("Unable to create release, [%s]", e.getMessage());
			result = false;
		}
		return result;
	}

	private void writeNewReleaseNotes(GHContent currentReleaseNotes, String tag, String releaseNotesFile, String branch,
			BuildListener listener) {
		if (currentReleaseNotes != null) {
			try {
				InputStream inputStream = currentReleaseNotes.read();
				StringWriter writer = new StringWriter();
				IOUtils.copy(inputStream, writer, "UTF-8");
				StringBuilder stringBuilder = new StringBuilder(RELEASE_NOTES_TEMPLATE);
				stringBuilder.append("\n\n");
				stringBuilder.append(RELEASE_NOTES_SEPARATOR);
				stringBuilder.append("\n\n");
				stringBuilder.append(writer.toString().replace("Next release", tag));

				currentReleaseNotes
						.update(stringBuilder.toString(), String.format("Updating %s after release %s", releaseNotesFile, tag),
								branch);
			} catch (IOException e) {
				listener.error("Unable to update release note file [%s], [%s]", releaseNotesFile, e.getMessage());
			}

		} else {
			try {
				ghRepository.createContent(RELEASE_NOTES_TEMPLATE + "\n" + RELEASE_NOTES_SEPARATOR + "\n",
						String.format("Updating %s after release %s", releaseNotesFile, tag),
						releaseNotesFile, branch);
			} catch (IOException e) {
				listener.error("Unable to create release note file [%s], [%s]", releaseNotesFile, e.getMessage());
			}
		}
	}

	@SuppressWarnings("unused")
{'fraction_non_alphanumeric': 0.11594824504968189, 'fraction_numerical': 0.000357423690042176, 'mean_word_length': 4.963341858482523, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3877076', 'n_tokens_mistral': 4649, 'n_tokens_neox': 3971, 'n_words': 970}