下面列出了hudson.model.Saveable#hudson.plugins.git.GitSCM 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
/**
* {@inheritDoc}
*/
@Override
public void onChange(Saveable o, XmlFile file) {
if (!(o instanceof Item)) {
// must be an Item
return;
}
SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem((Item) o);
if (item == null) {
// more specifically must be an SCMTriggerItem
return;
}
SCMTrigger trigger = item.getSCMTrigger();
if (trigger == null || trigger.isIgnorePostCommitHooks()) {
// must have the trigger enabled and not opted out of post commit hooks
return;
}
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
// we have a winner
GiteaWebhookListener.register(item, (GitSCM) scm);
}
}
}
@Override
public Revision decorateRevisionToBuild(GitSCM scm, Run<?, ?> build, GitClient git, TaskListener listener, Revision marked, Revision rev) throws IOException, InterruptedException, GitException {
listener.getLogger().println("Merging " + targetBranch.getName() + " commit " + targetBranch.getRevision().getHash() + " into merge-request head commit " + rev.getSha1String());
checkout(scm, build, git, listener, rev);
try {
git.setAuthor("Jenkins", /* could parse out of JenkinsLocationConfiguration.get().getAdminAddress() but seems overkill */"[email protected]");
git.setCommitter("Jenkins", "[email protected]");
MergeCommand cmd = git.merge().setRevisionToMerge(ObjectId.fromString(targetBranch.getRevision().getHash()));
for (GitSCMExtension ext : scm.getExtensions()) {
// By default we do a regular merge, allowing it to fast-forward.
ext.decorateMergeCommand(scm, build, git, listener, cmd);
}
cmd.execute();
} catch (GitException e) {
// Try to revert merge conflict markers.
checkout(scm, build, git, listener, rev);
throw e;
}
build.addAction(new MergeRecord(targetBranch.getRefSpec().destinationRef(targetBranch.getName()), targetBranch.getRevision().getHash())); // does not seem to be used, but just in case
ObjectId mergeRev = git.revParse(Constants.HEAD);
listener.getLogger().println("Merge succeeded, producing " + mergeRev.name());
return new Revision(mergeRev, rev.getBranches()); // note that this ensures Build.revision != Build.marked
}
/**
* Construct a SingleTestFlakyStatsWithRevision object with {@link SingleTestFlakyStats} and
* build information.
*
* @param stats Embedded {@link SingleTestFlakyStats} object
* @param build The {@link hudson.model.Run} object to get SCM information from.
*/
public SingleTestFlakyStatsWithRevision(SingleTestFlakyStats stats, Run build) {
this.stats = stats;
revision = Integer.toString(build.getNumber());
Job job = build.getParent();
SCMTriggerItem s = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job);
if (s != null) {
ArrayList<SCM> scms = new ArrayList<>(s.getSCMs());
SCM scm = scms.size() > 0 ? scms.get(0) : null;
if (scm != null && "hudson.plugins.git.GitSCM".equalsIgnoreCase(scm.getType())) {
GitSCM gitSCM = (GitSCM) scm;
BuildData buildData = gitSCM.getBuildData(build);
if (buildData != null) {
Revision gitRevision = buildData.getLastBuiltRevision();
if (gitRevision != null) {
revision = gitRevision.getSha1String();
}
}
}
}
}
@Test
public void redirectToBuildUrl() throws IOException, ExecutionException, InterruptedException, TimeoutException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.setScm(new GitSCM(gitRepoUrl));
testProject.setQuietPeriod(0);
QueueTaskFuture<FreeStyleBuild> future = testProject.scheduleBuild2(0);
FreeStyleBuild build = future.get(15, TimeUnit.SECONDS);
getBuildPageRedirectAction(testProject).execute(response);
verify(response).sendRedirect2(jenkins.getInstance().getRootUrl() + build.getUrl());
}
@Test
@ConfiguredWithReadme("gitscm/README.md")
public void configure_git() {
final GitSCM.DescriptorImpl descriptor = ExtensionList.lookupSingleton(GitSCM.DescriptorImpl.class);
assertNotNull(descriptor);
assertEquals("jenkins", descriptor.getGlobalConfigName());
assertEquals("[email protected]", descriptor.getGlobalConfigEmail());
assertTrue(descriptor.isCreateAccountBasedOnEmail());
}
private String retrieveRevisionToBuild(PushHook hook, GitSCM gitSCM) throws NoRevisionToBuildException {
if (inNoBranchDelete(hook)) {
if (gitSCM != null && gitSCM.getRepositories().size() == 1) {
String repositoryName = gitSCM.getRepositories().get(0).getName();
return hook.getRef().replaceFirst("^refs/heads", "remotes/" + repositoryName);
} else {
return hook.getAfter();
}
} else {
throw new NoRevisionToBuildException();
}
}
public static RepoInfo fromSqsJob(SQSJob sqsJob) {
if (sqsJob == null) {
return null;
}
RepoInfo repoInfo = new RepoInfo();
List<SCM> scms = sqsJob.getScmList();
List<String> codeCommitUrls = new ArrayList<>();
List<String> nonCodeCommitUrls = new ArrayList<>();
List<String> branches = new ArrayList<>();
for (SCM scm : scms) {
if (scm instanceof GitSCM) {//TODO refactor to visitor
GitSCM git = (GitSCM) scm;
List<RemoteConfig> repos = git.getRepositories();
for (RemoteConfig repo : repos) {
for (URIish urIish : repo.getURIs()) {
String url = urIish.toString();
if (StringUtils.isCodeCommitRepo(url)) {
codeCommitUrls.add(url);
}
else {
nonCodeCommitUrls.add(url);
}
}
}
for (BranchSpec branchSpec : git.getBranches()) {
branches.add(branchSpec.getName());
}
}
}
repoInfo.nonCodeCommitUrls = nonCodeCommitUrls;
repoInfo.codeCommitUrls = codeCommitUrls;
repoInfo.branches = branches;
return repoInfo;
}
public GitSCM createGit(String url, List<BranchSpec> branchSpecs) {
return new GitSCM(
GitSCM.createRepoList(url, null),
branchSpecs,
false,
Collections.<SubmoduleConfig>emptyList(),
null,
null,
Collections.<GitSCMExtension>emptyList()
);
}
public static MockGitSCM fromUrlAndBranchSpecs(String url, List<BranchSpec> branchSpecs) {
return new MockGitSCM(
GitSCM.createRepoList(url, null),
branchSpecs,
false,
Collections.<SubmoduleConfig>emptyList(),
null,
null,
Collections.<GitSCMExtension>emptyList()
);
}
/**
* Get the URL of the first declared repository in the project configuration.
* Use this as default source repository url.
*
* @return URIish the default value of the source repository url
* @throws IllegalStateException Project does not use git scm.
*/
private URIish getSourceRepoURLDefault(Job<?, ?> job) {
SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job);
GitSCM gitSCM = getGitSCM(item);
if (gitSCM == null) {
LOGGER.log(Level.WARNING, "Could not find GitSCM for project. Project = {1}, next build = {2}",
array(job.getName(), String.valueOf(job.getNextBuildNumber())));
throw new IllegalStateException("This project does not use git:" + job.getName());
}
return getFirstRepoURL(gitSCM.getRepositories());
}
public Issue32IT() throws IOException {
String sqsMessage = IOUtils.toString(Utils.getResource(this.getClass(), "us-east-1.json"), StandardCharsets.UTF_8);
GitSCM scm = MockGitSCM.fromSqsMessage(sqsMessage, "refs/heads/master");
this.fixture = new ProjectFixture()
.setSqsMessage(sqsMessage)
.setSubscribeInternalScm(true)
.setScm(scm)
.setShouldStarted(true);
}
public Issue30IT() throws IOException {
String sqsMessage = IOUtils.toString(Utils.getResource(this.getClass(), "us-east-1.json"), StandardCharsets.UTF_8);
GitSCM scm = MockGitSCM.fromSqsMessage(sqsMessage);
this.fixture = new ProjectFixture()
.setSqsMessage(sqsMessage)
.setSubscribeInternalScm(true)
.setScm(scm)
.setShouldStarted(Boolean.TRUE);
}
@Nonnull
public final GitSCM createSCM(GitLabSCMSource source) {
try {
return new GitSCM(getRemotes(source), getBranchSpecs(),
false, Collections.<SubmoduleConfig>emptyList(),
getBrowser(source.getProjectId(), source), null, getExtensions(source));
} catch (Exception e) {
throw new RuntimeException("error creating scm for source + " + source.getId(), e);
}
}
@Test
public void skip_approvedMR() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.addTrigger(trigger);
testProject.setScm(new GitSCM(gitRepoUrl));
executeMergeRequestAction(testProject, getJson("MergeRequestEvent_approvedMR.json"));
assertFalse(wouldFire);
}
@Test
public void notFoundBuild() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.setScm(new GitSCM(gitRepoUrl));
ByteArrayOutputStream out = new ByteArrayOutputStream();
mockResponse(out);
getBuildStatusAction(testProject).execute(response);
assertNotFoundBuild(out, response);
}
protected Action[] createActions(Job<?, ?> job, H hook) {
ArrayList<Action> actions = new ArrayList<>();
actions.add(new CauseAction(new GitLabWebHookCause(retrieveCauseData(hook))));
try {
SCMTriggerItem item = SCMTriggerItem.SCMTriggerItems.asSCMTriggerItem(job);
GitSCM gitSCM = getGitSCM(item);
actions.add(createRevisionParameter(hook, gitSCM));
} catch (NoRevisionToBuildException e) {
LOGGER.log(Level.WARNING, "unknown handled situation, dont know what revision to build for req {0} for job {1}",
new Object[]{hook, (job != null ? job.getFullName() : null)});
}
return actions.toArray(new Action[actions.size()]);
}
private GitSCM getGitSCM(SCMTriggerItem item) {
if (item != null) {
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
return (GitSCM) scm;
}
}
}
return null;
}
private boolean hasGitSCM(SCMTriggerItem item) {
if (item != null) {
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
return true;
}
}
}
return false;
}
@Test
public void given__cloud_branch_norev_userpass__when__build__then__scmBuilt() throws Exception {
createGitHubSCMSourceForTest(false, null);
BranchSCMHead head = new BranchSCMHead("test-branch");
source.setCredentialsId("user-pass");
GitHubSCMBuilder instance = new GitHubSCMBuilder(source, head, null);
assertThat(instance.credentialsId(), is("user-pass"));
assertThat(instance.head(), is(head));
assertThat(instance.revision(), is(nullValue()));
assertThat(instance.refSpecs(), contains("+refs/heads/test-branch:refs/remotes/@{remote}/test-branch"));
assertThat("expecting guess value until withGitHubRemote called",
instance.remote(), is("https://github.com/tester/test-repo.git"));
assertThat(instance.browser(), instanceOf(GithubWeb.class));
assertThat(instance.browser().getRepoUrl(), is("https://github.com/tester/test-repo"));
instance.withGitHubRemote();
assertThat(instance.remote(), is("https://github.com/tester/test-repo.git"));
GitSCM actual = instance.build();
assertThat(actual.getBrowser(), instanceOf(GithubWeb.class));
assertThat(actual.getBrowser().getRepoUrl(), is("https://github.com/tester/test-repo"));
assertThat(actual.getGitTool(), nullValue());
assertThat(actual.getUserRemoteConfigs(), hasSize(1));
UserRemoteConfig config = actual.getUserRemoteConfigs().get(0);
assertThat(config.getName(), is("origin"));
assertThat(config.getRefspec(), is("+refs/heads/test-branch:refs/remotes/origin/test-branch"));
assertThat(config.getUrl(), is("https://github.com/tester/test-repo.git"));
assertThat(config.getCredentialsId(), is("user-pass"));
RemoteConfig origin = actual.getRepositoryByName("origin");
assertThat(origin, notNullValue());
assertThat(origin.getURIs(), hasSize(1));
assertThat(origin.getURIs().get(0).toString(), is("https://github.com/tester/test-repo.git"));
assertThat(origin.getFetchRefSpecs(), hasSize(1));
assertThat(origin.getFetchRefSpecs().get(0).getSource(), is("refs/heads/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).getDestination(), is("refs/remotes/origin/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).isForceUpdate(), is(true));
assertThat(origin.getFetchRefSpecs().get(0).isWildcard(), is(false));
assertThat(actual.getExtensions(), contains(instanceOf(GitSCMSourceDefaults.class)));
}
@Test
public void build_acceptedMr() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
trigger.setTriggerOnAcceptedMergeRequest(true);
trigger.setTriggerOnMergeRequest(false);
testProject.addTrigger(trigger);
testProject.setScm(new GitSCM(gitRepoUrl));
QueueTaskFuture<?> future = testProject.scheduleBuild2(0, new ParametersAction(new StringParameterValue("gitlabTargetBranch", "master")));
future.get();
executeMergeRequestAction(testProject, getJson("MergeRequestEvent_merged.json"));
assertTrue(wouldFire);
}
@Test
public void given__server_branch_norev_anon__when__build__then__scmBuilt() throws Exception {
createGitHubSCMSourceForTest(true, "https://github.test/tester/test-repo.git");
BranchSCMHead head = new BranchSCMHead("test-branch");
source.setCredentialsId(null);
GitHubSCMBuilder instance = new GitHubSCMBuilder(source, head, null);
assertThat(instance.credentialsId(), is(nullValue()));
assertThat(instance.head(), is(head));
assertThat(instance.revision(), is(nullValue()));
assertThat(instance.refSpecs(), contains("+refs/heads/test-branch:refs/remotes/@{remote}/test-branch"));
assertThat("expecting guess value until withGitHubRemote called",
instance.remote(), is("https://github.test/tester/test-repo.git"));
assertThat(instance.browser(), instanceOf(GithubWeb.class));
assertThat(instance.browser().getRepoUrl(), is("https://github.test/tester/test-repo"));
instance.withGitHubRemote();
assertThat(instance.remote(), is("https://github.test/tester/test-repo.git"));
GitSCM actual = instance.build();
assertThat(actual.getBrowser(), instanceOf(GithubWeb.class));
assertThat(actual.getBrowser().getRepoUrl(), is("https://github.test/tester/test-repo"));
assertThat(actual.getGitTool(), nullValue());
assertThat(actual.getUserRemoteConfigs(), hasSize(1));
UserRemoteConfig config = actual.getUserRemoteConfigs().get(0);
assertThat(config.getName(), is("origin"));
assertThat(config.getRefspec(), is("+refs/heads/test-branch:refs/remotes/origin/test-branch"));
assertThat(config.getUrl(), is("https://github.test/tester/test-repo.git"));
assertThat(config.getCredentialsId(), is(nullValue()));
RemoteConfig origin = actual.getRepositoryByName("origin");
assertThat(origin, notNullValue());
assertThat(origin.getURIs(), hasSize(1));
assertThat(origin.getURIs().get(0).toString(), is("https://github.test/tester/test-repo.git"));
assertThat(origin.getFetchRefSpecs(), hasSize(1));
assertThat(origin.getFetchRefSpecs().get(0).getSource(), is("refs/heads/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).getDestination(), is("refs/remotes/origin/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).isForceUpdate(), is(true));
assertThat(origin.getFetchRefSpecs().get(0).isWildcard(), is(false));
assertThat(actual.getExtensions(), contains(instanceOf(GitSCMSourceDefaults.class)));
}
@Test
public void build_alreadyBuiltMR_differentTargetBranch() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.addTrigger(trigger);
testProject.setScm(new GitSCM(gitRepoUrl));
QueueTaskFuture<?> future = testProject.scheduleBuild2(0, new GitLabWebHookCause(causeData()
.withActionType(CauseData.ActionType.NOTE)
.withSourceProjectId(1)
.withTargetProjectId(1)
.withBranch("feature")
.withSourceBranch("feature")
.withUserName("")
.withSourceRepoHomepage("https://gitlab.org/test")
.withSourceRepoName("test")
.withSourceNamespace("test-namespace")
.withSourceRepoUrl("[email protected]:test.git")
.withSourceRepoSshUrl("[email protected]:test.git")
.withSourceRepoHttpUrl("https://gitlab.org/test.git")
.withMergeRequestTitle("Test")
.withMergeRequestId(1)
.withMergeRequestIid(1)
.withTargetBranch("master")
.withTargetRepoName("test")
.withTargetNamespace("test-namespace")
.withTargetRepoSshUrl("[email protected]:test.git")
.withTargetRepoHttpUrl("https://gitlab.org/test.git")
.withTriggeredByUser("test")
.withLastCommit("123")
.withTargetProjectUrl("https://gitlab.org/test")
.build()));
future.get();
exception.expect(HttpResponses.HttpResponseException.class);
new NoteBuildAction(testProject, getJson("NoteEvent_alreadyBuiltMR.json"), null).execute(response);
verify(trigger).onPost(any(NoteHook.class));
}
@Test
public void given__server_branch_norev_userkey__when__build__then__scmBuilt() throws Exception {
createGitHubSCMSourceForTest(true, "https://github.test/tester/test-repo.git");
BranchSCMHead head = new BranchSCMHead("test-branch");
source.setCredentialsId("user-key");
GitHubSCMBuilder instance = new GitHubSCMBuilder(source, head, null);
assertThat(instance.credentialsId(), is("user-key"));
assertThat(instance.head(), is(head));
assertThat(instance.revision(), is(nullValue()));
assertThat(instance.refSpecs(), contains("+refs/heads/test-branch:refs/remotes/@{remote}/test-branch"));
assertThat("expecting guess value until withGitHubRemote called",
instance.remote(), is("https://github.test/tester/test-repo.git"));
assertThat(instance.browser(), instanceOf(GithubWeb.class));
assertThat(instance.browser().getRepoUrl(), is("https://github.test/tester/test-repo"));
instance.withGitHubRemote();
assertThat(instance.remote(), is("[email protected]:tester/test-repo.git"));
GitSCM actual = instance.build();
assertThat(actual.getBrowser(), instanceOf(GithubWeb.class));
assertThat(actual.getBrowser().getRepoUrl(), is("https://github.test/tester/test-repo"));
assertThat(actual.getGitTool(), nullValue());
assertThat(actual.getUserRemoteConfigs(), hasSize(1));
UserRemoteConfig config = actual.getUserRemoteConfigs().get(0);
assertThat(config.getName(), is("origin"));
assertThat(config.getRefspec(), is("+refs/heads/test-branch:refs/remotes/origin/test-branch"));
assertThat(config.getUrl(), is("[email protected]:tester/test-repo.git"));
assertThat(config.getCredentialsId(), is("user-key"));
RemoteConfig origin = actual.getRepositoryByName("origin");
assertThat(origin, notNullValue());
assertThat(origin.getURIs(), hasSize(1));
assertThat(origin.getURIs().get(0).toString(), is("[email protected]:tester/test-repo.git"));
assertThat(origin.getFetchRefSpecs(), hasSize(1));
assertThat(origin.getFetchRefSpecs().get(0).getSource(), is("refs/heads/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).getDestination(), is("refs/remotes/origin/test-branch"));
assertThat(origin.getFetchRefSpecs().get(0).isForceUpdate(), is(true));
assertThat(origin.getFetchRefSpecs().get(0).isWildcard(), is(false));
assertThat(actual.getExtensions(), contains(instanceOf(GitSCMSourceDefaults.class)));
}
@Test
public void successfulBuild() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.setScm(new GitSCM(gitRepoUrl));
FreeStyleBuild build = testProject.scheduleBuild2(0).get();
ByteArrayOutputStream out = new ByteArrayOutputStream();
mockResponse(out);
getBuildStatusAction(testProject).execute(response);
assertSuccessfulBuild(build, out, response);
}
@Test
public void build_alreadyBuiltMR_differentTargetBranch() throws IOException, ExecutionException, InterruptedException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.addTrigger(trigger);
testProject.setScm(new GitSCM(gitRepoUrl));
QueueTaskFuture<?> future = testProject.scheduleBuild2(0, new GitLabWebHookCause(causeData()
.withActionType(CauseData.ActionType.MERGE)
.withSourceProjectId(1)
.withTargetProjectId(1)
.withBranch("feature")
.withSourceBranch("feature")
.withUserName("")
.withSourceRepoHomepage("https://gitlab.org/test")
.withSourceRepoName("test")
.withSourceNamespace("test-namespace")
.withSourceRepoUrl("[email protected]:test.git")
.withSourceRepoSshUrl("[email protected]:test.git")
.withSourceRepoHttpUrl("https://gitlab.org/test.git")
.withMergeRequestTitle("Test")
.withMergeRequestId(1)
.withMergeRequestIid(1)
.withTargetBranch("master")
.withTargetRepoName("test")
.withTargetNamespace("test-namespace")
.withTargetRepoSshUrl("[email protected]:test.git")
.withTargetRepoHttpUrl("https://gitlab.org/test.git")
.withTriggeredByUser("test")
.withLastCommit("123")
.withTargetProjectUrl("https://gitlab.org/test")
.build()));
future.get();
executeMergeRequestAction(testProject, getJson("MergeRequestEvent_alreadyBuiltMR_differentTargetBranch.json"));
assertTrue(wouldFire);
}
private GitSCM getGitSCM(SCMTriggerItem item) {
if (item != null) {
for (SCM scm : item.getSCMs()) {
if (scm instanceof GitSCM) {
return (GitSCM) scm;
}
}
}
return null;
}
@Test
public void skip_alreadyBuiltMR() throws Exception {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.addTrigger(trigger);
testProject.setScm(new GitSCM(gitRepoUrl));
executeMergeRequestAction(testProject, getJson("MergeRequestEvent_alreadyBuiltMR_initialBuild.json"));
jenkins.waitUntilNoActivity();
executeMergeRequestAction(testProject, getJson("MergeRequestEvent_alreadyBuiltMR.json"));
assertFalse(wouldFire);
}
@Test
public void redirectToBuildStatusUrl() throws IOException, ExecutionException, InterruptedException, TimeoutException {
FreeStyleProject testProject = jenkins.createFreeStyleProject();
testProject.setScm(new GitSCM(gitRepoUrl));
testProject.setQuietPeriod(0);
QueueTaskFuture<FreeStyleBuild> future = testProject.scheduleBuild2(0);
FreeStyleBuild build = future.get(15, TimeUnit.SECONDS);
doThrow(IOException.class).when(response).sendRedirect2(jenkins.getInstance().getRootUrl() + build.getUrl());
getBuildPageRedirectAction(testProject).execute(response);
verify(response).sendRedirect2(jenkins.getInstance().getRootUrl() + build.getBuildStatusUrl());
}
private static <T extends GitSCMExtension> T getExtension(GitSCM scm, Class<T> type) {
for (GitSCMExtension e : scm.getExtensions()) {
if (type.isInstance(e)) {
return type.cast(e);
}
}
return null;
}
@Override
public GitSCM createScm(GitHubSCMSource scmSource, SCMHead scmHead, SCMRevision scmRevision) {
return new GitSCM(
gitSCM.getUserRemoteConfigs(),
gitSCM.getBranches(),
gitSCM.isDoGenerateSubmoduleConfigurations(),
gitSCM.getSubmoduleCfg(),
gitSCM.getBrowser(),
gitSCM.getGitTool(),
gitSCM.getExtensions()
);
}