Java源码示例:hudson.scm.ChangeLogSet

示例1
private WorkflowRun workflowRunWithIssuesAboveLimit() {
    int count = 105;
    Object[] changeSetEntries = new Object[count];
    for (int i = 0; i < count; i++) {
        final ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);
        when(entry.getMsg()).thenReturn(String.format("TEST-%d Commit message for %d", i, i));
        changeSetEntries[i] = entry;
    }
    final ChangeLogSet changeLogSet = mock(ChangeLogSet.class);

    when(changeLogSet.getItems()).thenReturn(changeSetEntries);
    final WorkflowRun workflowRun = mock(WorkflowRun.class);

    when(workflowRun.getChangeSets()).thenReturn(ImmutableList.of(changeLogSet));
    return workflowRun;
}
 
示例2
@Override
public Collection<BlueIssue> getIssues(ChangeLogSet.Entry changeSetEntry) {
    Run run = changeSetEntry.getParent().getRun();
    final JiraSite site = JiraSite.get(run.getParent());
    if (site == null) {
        return null;
    }
    final JiraBuildAction action = run.getAction(JiraBuildAction.class);
    if (action == null) {
        return null;
    }
    Collection<String> issueKeys = findIssueKeys(changeSetEntry.getMsg(), site.getIssuePattern());
    Iterable<BlueIssue> transformed = Iterables.transform(issueKeys,
                                                          s -> BlueJiraIssue.create(site, action.getIssue(s)));
    return ImmutableList.copyOf(Iterables.filter(transformed, Predicates.notNull()));
}
 
示例3
private static ChangeLogSet build( String... texts) {
    List<ChangeLogSet.Entry> entries = Arrays.asList( texts ).stream().map( text -> {
        final ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);
        when(entry.getMsg()).thenReturn(text);
        return  entry;
    } ).collect( Collectors.toList() );

    return new ChangeLogSet<ChangeLogSet.Entry>(null, null) {
        @Override
        public boolean isEmptySet() {
            return false;
        }

        @Override
        public Iterator<Entry> iterator() {
            return entries.iterator();
        }
    };
}
 
示例4
@Test
public void testChangeSet(){
    Reachable reachable = mock(Reachable.class);
    when(reachable.getLink()).thenReturn(new Link("/foo/bar"));
    User user = mock(User.class);
    when(user.getId()).thenReturn("vivek");
    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);
    when(entry.getAuthor()).thenReturn(user);
    when(entry.getTimestamp()).thenReturn(System.currentTimeMillis());
    when(entry.getCommitId()).thenReturn("12345");
    when(entry.getMsg()).thenReturn("test changeset");
    when(entry.getAffectedPaths()).thenReturn(Collections.singleton("/foo/bar"));
    ChangeSetResource changeSetResource = new ChangeSetResource(new OrganizationImpl("testorg", mock(Folder.class)), entry, reachable);
    assertEquals(user.getId(), changeSetResource.getAuthor().getId());
    assertEquals(entry.getCommitId(), changeSetResource.getCommitId());
    assertEquals(entry.getMsg(), changeSetResource.getMsg());
}
 
示例5
/**
 * Finds any issues associated with the changeset
 * e.g. a commit message could be "TICKET-123 fix all the things" and be associated with TICKET-123 in JIRA
 * @param changeSetEntry entry
 * @return issues representing the change
 */
public static Collection<BlueIssue> resolve(ChangeLogSet.Entry changeSetEntry) {
    LinkedHashSet<BlueIssue> allIssues = Sets.newLinkedHashSet();
    for (BlueIssueFactory factory : ExtensionList.lookup(BlueIssueFactory.class)) {
        try {
            Collection<BlueIssue> issues = factory.getIssues(changeSetEntry);
            if (issues == null) {
                continue;
            }
            allIssues.addAll(issues);
        } catch (Exception e) {
            LOGGER.log(Level.WARNING,"Unable to fetch issues for changeSetEntry " + e.getMessage(), e);
        }
    }
    return allIssues;
}
 
示例6
@Override
public Collection<BlueIssue> getIssues(ChangeLogSet.Entry changeSetEntry) {
    Job job = changeSetEntry.getParent().getRun().getParent();
    if (!(job.getParent() instanceof MultiBranchProject)) {
        return null;
    }
    MultiBranchProject mbp = (MultiBranchProject)job.getParent();
    List<SCMSource> scmSources = (List<SCMSource>) mbp.getSCMSources();
    SCMSource source = scmSources.isEmpty() ? null : scmSources.get(0);
    if (!(source instanceof GitHubSCMSource)) {
        return null;
    }
    GitHubSCMSource gitHubSource = (GitHubSCMSource)source;
    String apiUri =  gitHubSource.getApiUri();
    final String repositoryUri = new HttpsRepositoryUriResolver().getRepositoryUri(apiUri, gitHubSource.getRepoOwner(), gitHubSource.getRepository());
    Collection<BlueIssue> results = new ArrayList<>();
    for (String input : findIssueKeys(changeSetEntry.getMsg())) {
        String uri = repositoryUri.substring(0, repositoryUri.length() - 4);
        results.add(new GithubIssue("#" + input, String.format("%s/issues/%s", uri, input)));
    }
    return results;
}
 
示例7
@Test
public void changeSetEntryIsNotGithub() throws Exception {
    MultiBranchProject project = mock(MultiBranchProject.class);
    Job job = mock(MockJob.class);
    Run run = mock(Run.class);
    ChangeLogSet logSet = mock(ChangeLogSet.class);
    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);

    when(project.getProperties()).thenReturn(new DescribableList(project));
    when(entry.getParent()).thenReturn(logSet);
    when(logSet.getRun()).thenReturn(run);
    when(run.getParent()).thenReturn(job);
    when(job.getParent()).thenReturn(project);

    when(entry.getMsg()).thenReturn("Closed #123 #124");
    when(project.getSCMSources()).thenReturn(Lists.newArrayList(new GitSCMSource("http://example.com/repo.git")));

    Collection<BlueIssue> resolved = BlueIssueFactory.resolve(entry);
    Assert.assertEquals(0, resolved.size());
}
 
示例8
@Test
public void changeSetJobParentNotMultibranch() throws Exception {
    AbstractFolder project = mock(AbstractFolder.class);
    Job job = mock(MockJob.class);
    Run run = mock(Run.class);
    ChangeLogSet logSet = mock(ChangeLogSet.class);
    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);

    when(project.getProperties()).thenReturn(new DescribableList(project));
    when(entry.getParent()).thenReturn(logSet);
    when(logSet.getRun()).thenReturn(run);
    when(run.getParent()).thenReturn(job);
    when(job.getParent()).thenReturn(project);

    when(entry.getMsg()).thenReturn("Closed #123 #124");

    Collection<BlueIssue> resolved = BlueIssueFactory.resolve(entry);
    Assert.assertEquals(0, resolved.size());
}
 
示例9
public void addDevelopers() {
    if (!(run instanceof RunWithSCM)) {
        return;
    }
    RunWithSCM runWithSCM = (RunWithSCM) run;

    List<ChangeLogSet<ChangeLogSet.Entry>> sets = runWithSCM.getChangeSets();

    Set<User> authors = new HashSet<>();
    sets.stream()
            .filter(set -> set instanceof ChangeLogSet)
            .forEach(set -> set
                    .forEach(entry -> authors.add(entry.getAuthor())));

    addFact(NAME_DEVELOPERS, StringUtils.join(sortUsers(authors), ", "));
}
 
示例10
@Test
public void addDevelopers_AddsFactWithSortedAuthors() {

    // given
    List<ChangeLogSet> files = new AffectedFileBuilder().sampleChangeLogs(run);
    when(run.getChangeSets()).thenReturn(files);

    FactsBuilder factBuilder = new FactsBuilder(run, taskListener);

    // when
    factBuilder.addDevelopers();

    // then
    String[] sortedAuthors = {AffectedFileBuilder.sampleAuthors[2], AffectedFileBuilder.sampleAuthors[1], AffectedFileBuilder.sampleAuthors[0]};
    FactAssertion.assertThat(factBuilder.collect())
            .hasName(FactsBuilder.NAME_DEVELOPERS)
            .hasValue(StringUtils.join(sortedAuthors, ", "));
}
 
示例11
static ChangeLogSet<? extends ChangeLogSet.Entry> getChangeLogSet(Run<?, ?> build) {
    if (build instanceof AbstractBuild) {
        return ((AbstractBuild<?, ?>) build).getChangeSet();
    }
    ItemGroup<?> itemGroup = build.getParent().getParent();
    for (Item item : itemGroup.getItems()) {
        if (!item.getFullDisplayName().equals(build.getFullDisplayName())
                && !item.getFullDisplayName().equals(build.getParent().getFullDisplayName())) {
            continue;
        }

        for (Job<?, ?> job : item.getAllJobs()) {
            if (job instanceof AbstractProject<?, ?>) {
                AbstractProject<?, ?> project = (AbstractProject<?, ?>) job;
                return project.getBuilds().getLastBuild().getChangeSet();
            }
        }
    }
    return ChangeLogSet.createEmpty(build);
}
 
示例12
/**
 * Parse a Jira ticket number, ie SSD-101, out of the given ChangeLogSet.Entry.
 *
 * Ticket number is assumed to be the first word of the commit message
 *
 * @param change - the change entry to
 * @return
 */
@Override
public List<JiraCommit> getJiraIssuesFromChangeSet(final ChangeLogSet.Entry change)
{
    String msg = change.getMsg();
    String firstWordOfTicket;
    firstWordOfTicket = msg.substring(0, (msg.contains(" ") ? StringUtils.indexOf(msg, " ") : msg.length()));

    final String regex = "([A-Z][0-9A-Z_]+-)([0-9]+)";
    final Pattern pattern = Pattern.compile(regex);
    final Matcher matcher = pattern.matcher(firstWordOfTicket);

    if (!matcher.find())
    {
        return null;
    }

    List<String> jiraPrefixes = Config.getGlobalConfig().getJiraTickets();

    if (jiraPrefixes.contains(matcher.group(1)))
    {
        return Arrays.asList(new JiraCommit(matcher.group(0), change));
    }

    return null;
}
 
示例13
@Test
public void testSimpleCase()
        throws Exception
{
    List<ChangeLogSet.Entry> validChanges = Arrays.asList(
            MockChangeLogUtil.mockChangeLogSetEntry("Hello World [FOO-101]"),
            MockChangeLogUtil.mockChangeLogSetEntry("FOO-101 ticket at start"),
            MockChangeLogUtil.mockChangeLogSetEntry("In the middle FOO-101 of the message"),
            MockChangeLogUtil.mockChangeLogSetEntry("Weird characters FOO-101: next to it"));
    for (ChangeLogSet.Entry change : validChanges)
    {
        assertThat(strategy.getJiraIssuesFromChangeSet(change).size(), equalTo(1));
        assertThat(strategy.getJiraIssuesFromChangeSet(change).get(0).getJiraTicket(), equalTo("FOO-101"));
    }

}
 
示例14
private void setContent() {
  if (build.getChangeSet().getItems().length == 0) {
    message.setContent(this.getResultString());
  } else {
    StringBuilder changes = new StringBuilder();

    for (Iterator<? extends ChangeLogSet.Entry> i = build.getChangeSet().iterator(); i.hasNext(); ) {
      ChangeLogSet.Entry change = i.next();
      changes.append("\n");
      changes.append(change.getMsg());
      changes.append(" - ");
      changes.append(change.getAuthor());
    }

    message.setContent(String.format("%s%n%s", this.getResultString(), changes.toString()));
  }
}
 
示例15
private String getChangeSet(Run<?, ?> build) {
    StringBuilder changeString = new StringBuilder();
    RunChangeSetWrapper wrapper = new RunChangeSetWrapper(build);
    if (!wrapper.hasChangeSetComputed()) {
        changeString.append("Could not determine changes since last build.");
    } else if (wrapper.hasChangeSet()) {
        // If there seems to be a commit message at all, try to list all the changes.
        changeString.append("Changes since last build:\n");
        for (ChangeLogSet<? extends ChangeLogSet.Entry> changeLogSet : wrapper.getChangeSets()) {
            for (ChangeLogSet.Entry e : changeLogSet) {
                String commitMsg = e.getMsg().trim();
                if (commitMsg.length() > 47) {
                    commitMsg = commitMsg.substring(0, 46) + "...";
                }
                String author = e.getAuthor().getDisplayName();
                changeString.append("\n* `").append(author).append("` ").append(commitMsg);
            }
        }
    }
    return changeString.toString();
}
 
示例16
@Override
protected Set<String> getCommittersForRun(Run<?, ?> run) {
    WorkflowRun workflowRun = (WorkflowRun) run;
    Set<String> committers = new TreeSet<String>();
    for (ChangeLogSet<? extends ChangeLogSet.Entry> changeLogSet : workflowRun.getChangeSets()) {
        Iterables
            .addAll(committers, transform(nonNullIterable(changeLogSet), new Function<ChangeLogSet.Entry, String>
                () {
                @Override
                public String apply(@Nullable ChangeLogSet.Entry entry) {
                    return entry != null ? entry.getAuthor().getFullName() : null;
                }
            }));
    }
    return committers;
}
 
示例17
public Set<String> extractIssueKeys(final WorkflowRun workflowRun) {

        final Set<IssueKey> allIssueKeys = new HashSet<>();
        final List<ChangeLogSet<? extends ChangeLogSet.Entry>> changeSets =
                workflowRun.getChangeSets();

        for (ChangeLogSet<? extends ChangeLogSet.Entry> changeSet : changeSets) {
            final Object[] changeSetEntries = changeSet.getItems();
            for (Object item : changeSetEntries) {
                final ChangeLogSet.Entry changeSetEntry = (ChangeLogSet.Entry) item;

                if (changeSetEntry instanceof GitChangeSet) {
                    allIssueKeys.addAll(
                            IssueKeyStringExtractor.extractIssueKeys(
                                    ((GitChangeSet) changeSetEntry).getComment()));
                }
                allIssueKeys.addAll(
                        IssueKeyStringExtractor.extractIssueKeys(changeSetEntry.getMsg()));

                if (allIssueKeys.size() >= ISSUE_KEY_MAX_LIMIT) {
                    break;
                }
            }
        }

        return allIssueKeys
                .stream()
                .limit(ISSUE_KEY_MAX_LIMIT)
                .map(IssueKey::toString)
                .collect(Collectors.toSet());
    }
 
示例18
private WorkflowRun changeSetWithOneChangeSetEntry() {
    final ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);
    when(entry.getMsg()).thenReturn("TEST-123 Commit message");
    final ChangeLogSet changeLogSet = mock(ChangeLogSet.class);
    when(changeLogSet.getItems()).thenReturn(new Object[] {entry});
    final WorkflowRun workflowRun = mock(WorkflowRun.class);

    when(workflowRun.getChangeSets()).thenReturn(ImmutableList.of(changeLogSet));
    return workflowRun;
}
 
示例19
private WorkflowRun changeSetWithMultipleChangeSetEntries() {
    final ChangeLogSet.Entry entry1 = mock(ChangeLogSet.Entry.class);
    final ChangeLogSet.Entry entry2 = mock(ChangeLogSet.Entry.class);
    when(entry1.getMsg()).thenReturn("TEST-123 Commit message");
    when(entry2.getMsg()).thenReturn("TEST-456 Commit message");
    final ChangeLogSet changeLogSet = mock(ChangeLogSet.class);
    when(changeLogSet.getItems()).thenReturn(new Object[] {entry1, entry2});
    final WorkflowRun workflowRun = mock(WorkflowRun.class);

    when(workflowRun.getChangeSets()).thenReturn(ImmutableList.of(changeLogSet));
    return workflowRun;
}
 
示例20
private WorkflowRun workflowRunWithMultipleChangeSets() {
    final ChangeLogSet.Entry entry1 = mock(ChangeLogSet.Entry.class);
    final ChangeLogSet.Entry entry2 = mock(ChangeLogSet.Entry.class);
    when(entry1.getMsg()).thenReturn("TEST-123 Commit message");
    when(entry2.getMsg()).thenReturn("TEST-456 Commit message");
    final ChangeLogSet changeLogSet1 = mock(ChangeLogSet.class);
    final ChangeLogSet changeLogSet2 = mock(ChangeLogSet.class);
    when(changeLogSet1.getItems()).thenReturn(new Object[] {entry1});
    when(changeLogSet2.getItems()).thenReturn(new Object[] {entry2});
    final WorkflowRun workflowRun = mock(WorkflowRun.class);

    when(workflowRun.getChangeSets())
            .thenReturn(ImmutableList.of(changeLogSet1, changeLogSet2));
    return workflowRun;
}
 
示例21
private WorkflowRun changeSetWithSquashedCommitsInComment() {
    final GitChangeSet entry = mock(GitChangeSet.class);
    when(entry.getComment())
            .thenReturn(
                    "Squashed Commit title (#12)\n"
                            + "* TEST-3 Fix bug #1\n"
                            + "\n"
                            + "* TEST-4 Fix bug #2\n");
    final ChangeLogSet changeLogSet = mock(ChangeLogSet.class);
    when(changeLogSet.getItems()).thenReturn(new Object[] {entry});
    final WorkflowRun workflowRun = mock(WorkflowRun.class);

    when(workflowRun.getChangeSets()).thenReturn(ImmutableList.of(changeLogSet));
    return workflowRun;
}
 
示例22
static Collection<String> getIssueKeys(ChangeLogSet<?> changelog, Pattern issuePattern) {
    Set<String> issueKeys = new HashSet<>();
    for (ChangeLogSet.Entry entry : changelog) {
        issueKeys.addAll(BlueJiraIssue.findIssueKeys(entry.getMsg(), issuePattern));
    }
    return issueKeys;
}
 
示例23
@Test
public void issuesForChangeSetItemForSite() throws Exception {
    Job job = mock(Job.class);
    Run run = mock(Run.class);
    ChangeLogSet logSet = mock(ChangeLogSet.class);
    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);

    when(entry.getParent()).thenReturn(logSet);
    when(logSet.getRun()).thenReturn(run);
    when(run.getParent()).thenReturn(job);

    Assert.assertTrue(BlueIssueFactory.resolve(entry).isEmpty());
}
 
示例24
@Test
public void changeSetHasNoJiraIssue() throws Exception {
    JiraSCMListener listener = new JiraSCMListener();

    Job job = mock(Job.class);
    Run run = mock(Run.class);
    ChangeLogSet logSet = mock(ChangeLogSet.class);
    final ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);

    when(entry.getParent()).thenReturn(logSet);
    when(logSet.getRun()).thenReturn(run);
    when(run.getParent()).thenReturn(job);
    when(entry.getMsg()).thenReturn("No jira ticket here");

    ChangeLogSet<ChangeLogSet.Entry> set = new ChangeLogSet<ChangeLogSet.Entry>(run, null) {
        @Override
        public boolean isEmptySet() {
            return false;
        }

        @Override
        public Iterator<Entry> iterator() {
            return Collections.singletonList(entry).iterator();
        }
    };

    // Setup JIRA site
    mockStatic(JiraSite.class);
    JiraSite site = mock(JiraSite.class);

    when(site.getIssuePattern()).thenReturn(JiraSite.DEFAULT_ISSUE_PATTERN);
    when(JiraSite.get(job)).thenReturn(site);

    JiraBuildAction action = new JiraBuildAction(run, new HashSet());
    when(run.getAction(JiraBuildAction.class)).thenReturn(action);

    listener.onChangeLogParsed(run, null,null, set);

    Assert.assertTrue(action.getIssues().isEmpty());
}
 
示例25
@Test
public void uniqueIssueKeys() throws Exception {
    ChangeLogSet<ChangeLogSet.Entry> entries = build( "TST-123", "TST-123", "TST-123", "TST-124",
                                                      "TST-123", "TST-124", "TST-125");
    Collection<String> keys = JiraSCMListener.getIssueKeys( entries, JiraSite.DEFAULT_ISSUE_PATTERN );
    Assert.assertEquals(3, keys.size());
}
 
示例26
@Test
public void changeSetEntry() throws Exception {
    MultiBranchProject project = mock(MultiBranchProject.class);
    Job job = mock(MockJob.class);
    Run run = mock(Run.class);
    ChangeLogSet logSet = mock(ChangeLogSet.class);
    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);

    when(project.getProperties()).thenReturn(new DescribableList(project));
    when(entry.getParent()).thenReturn(logSet);
    when(logSet.getRun()).thenReturn(run);
    when(run.getParent()).thenReturn(job);
    when(job.getParent()).thenReturn(project);

    GitHubSCMSource source = new GitHubSCMSource("foo", null, null, null, "example", "repo");
    when(project.getSCMSources()).thenReturn(Lists.newArrayList(source));

    when(entry.getMsg()).thenReturn("Closed #123 #124");

    Collection<BlueIssue> resolved = BlueIssueFactory.resolve(entry);
    Assert.assertEquals(2, resolved.size());

    Map<String, BlueIssue> issueMap = Maps.uniqueIndex(resolved, new Function<BlueIssue, String>() {
        @Override
        public String apply(BlueIssue input) {
            return input.getId();
        }
    });

    BlueIssue issue123 = issueMap.get("#123");
    Assert.assertEquals("https://github.com/example/repo/issues/123", issue123.getURL());

    BlueIssue issue124 = issueMap.get("#124");
    Assert.assertEquals("https://github.com/example/repo/issues/124", issue124.getURL());
}
 
示例27
public List<ChangeLogSet> sampleChangeLogs(AbstractBuild run) {
    ChangeLogSet.Entry entryPeter = mockEntry(sampleAuthors[0]);
    ChangeLogSet.Entry entryGeorge = mockEntry(sampleAuthors[1]);
    ChangeLogSet.Entry entryAnn = mockEntry(sampleAuthors[2]);

    when(entryPeter.getAffectedFiles()).thenAnswer(createAnswer(Arrays.asList(new File(), new File())));
    when(entryPeter.getAffectedFiles()).thenAnswer(createAnswer(Collections.emptyList()));
    when(entryAnn.getAffectedFiles()).thenAnswer(createAnswer(Collections.emptyList()));

    return Arrays.asList(new ChangeLogSetBuilder(run, entryPeter, entryGeorge, entryAnn));
}
 
示例28
private ChangeLogSet.Entry mockEntry(String userName) {
    User user = mockUser(userName);
    when(user.getFullName()).thenReturn(userName);

    ChangeLogSet.Entry entry = mock(ChangeLogSet.Entry.class);
    when(entry.getAuthor()).thenReturn(user);

    return entry;
}
 
示例29
/**
 * @return true if all APKs have been published successfully.
 */
private boolean publishFabric(Run build, EnvVars environment, FilePath workspace, PrintStream logger,
                              ChangeLogSet<? extends ChangeLogSet.Entry> changeLogSet)
        throws InterruptedException, IOException {
    logger.println("Fabric Beta Publisher Plugin:");

    File manifestFile = getManifestFile();

    File crashlyticsToolsFile = prepareCrashlytics(logger, manifestFile);
    if (crashlyticsToolsFile == null) {
        return false;
    }

    String releaseNotes = getReleaseNotes(
            changeLogSet, releaseNotesType, releaseNotesParameter, releaseNotesFile, environment, workspace);

    EnvVarsAction envVarsAction = null;
    if (!Strings.isNullOrEmpty(organization)) {
        envVarsAction = new EnvVarsAction();
    } else {
        logger.println("Skipped constructing Fabric Beta link because organization is not set.");
    }

    List<FilePath> apkFilePaths = getApkFilePaths(environment, workspace);
    boolean success = !apkFilePaths.isEmpty();
    for (int apkIndex = 0; apkIndex < apkFilePaths.size(); apkIndex++) {
        success &= uploadApkFile(envVarsAction, apkIndex, environment, logger, manifestFile, crashlyticsToolsFile,
                releaseNotes, apkFilePaths.get(apkIndex));
    }
    if (envVarsAction != null) {
        build.addAction(envVarsAction);
    }
    FileUtils.delete(logger, manifestFile, crashlyticsToolsFile);
    return success;
}
 
示例30
static String getReleaseNotes(ChangeLogSet<? extends ChangeLogSet.Entry> changeLogSet, String releaseNotesType,
                              String releaseNotesParameter, String releaseNotesFile, EnvVars environment,
                              FilePath workspace)
        throws IOException, InterruptedException {
    switch (releaseNotesType) {
        case RELEASE_NOTES_TYPE_NONE:
            return null;
        case RELEASE_NOTES_TYPE_PARAMETER:
            return environment.get(releaseNotesParameter, "");
        case RELEASE_NOTES_TYPE_CHANGELOG:
            StringBuilder sb = new StringBuilder();
            if (!changeLogSet.isEmptySet()) {
                boolean hasManyChangeSets = changeLogSet.getItems().length > 1;
                for (ChangeLogSet.Entry entry : changeLogSet) {
                    sb.append("\n");
                    if (hasManyChangeSets) {
                        sb.append("* ");
                    }
                    sb.append(entry.getMsg());
                }
            }
            return sb.toString();
        case RELEASE_NOTES_TYPE_FILE:
            FilePath releaseNotesFilePath = new FilePath(workspace, environment.expand(releaseNotesFile));
            return releaseNotesFilePath.readToString();
        default:
            return null;
    }
}