I want to develop a hook that will automatically merge a branch (always the same one) into the master when smth happens. This should happen because there are some strange diffs when pull requests are opened and we found out that this merging is the solution.
So I am working with the BitBucket Server API and I found the class PullRequestCreateRequest and the interface PullRequestService
This is what I got atm:
if (MYCONDITION)
{
PullRequestImpl pullRequest = new PullRequestImpl(); //class that implements PullRequestService
PullRequestCreateRequest prCreate = new PullRequestCreateRequest.Builder()
.title("Automatic Merge Branch Foo Into Master")
.description("blablabla")
.repository(request.getRepository()) //from head of the method
//.fromBranch("MyBranch") HELP pls
.toBranchId("master")
.build();
pullRequest.create(prCreate);
pullRequest.merge(prCreate);
}
My Problem is, that I don't know how to specify my source branch. I searched in the Doc, but just found some RefIds, etc.
Has someone an idea?
Btw: I create the PR first because it's not allowed to merge directly into the master and I can't change this.
Use fromRefId():
PullRequestCreateRequest prCreate = new PullRequestCreateRequest.Builder()
.title("Automatic Merge Branch Foo Into Master")
.description("blablabla")
.repository(request.getRepository())
.fromRefId("Foo") //<-- here you go
.toBranchId("master")
.build();
Related
I have seen a lot of tutorials but I haven't found any code for getting all the files and folders in a particular branch.
I have tried this piece of code
File src = new File("C:\\Users\\Winfo\\Documents\\GitHub\\WDAS");
org.eclipse.jgit.lib.Repository repo = new FileRepositoryBuilder().readEnvironment().findGitDir(src).build();
Git git = new Git(repo);
git.checkout()
.setName("new-branch")
.setStartPoint("commit id") // commit id here
.call();
This is creating a separate Branch based on the commit id, but I need to clone the list of files and folders in a local repository based on the branch.
I am new to JGit, could someone help with my requirement. Thanks in advance
You may do something like this below to pull from a particular branch
Git.cloneRepository()
.setURI("https://github.com/eclipse/jgit.git") // your git url
.setDirectory(new File("/path/to/repo"))
.setBranchesToClone(Arrays.asList("refs/heads/specific-branch"))// give ur branch name
.setBranch("refs/heads/specific-branch")
.call();
For more information: read here
First, some background why I want this crazy thing. I'm building a Plugin in Jenkins that provides an API for scripts that are started from a pipeline-script to independently communicate with jenkins.
For example a shell-script can then tell jenkins to start a new stage from the running script.
I've got the communication between the script and Jenkins working, but the problem is that I now want to try and start a stage from a callback in my code but I can't seem to figure out how to do it.
Stuff I've tried and failed at:
Start a new StageStep.java
I can't seem to find a way to correctly instantiate and inject the step into the lifecycle. I've looked into DSL.java, but cant seem to get to an instance to call invokeStep(), nor was I able to find out how to instantiate DSL.java with the right environment.
Look at StageStepExecution.java and do what it does.
It seems to either invoke the body with an Environment Variable and nothing else, or set some actions and save the state in a config file when it has no body. I could not find out how the Pipeline: Stage View Plugin hooks into this, but it doesn't seem to read the config file. I've tried setting the Actions (even the inner class through reflection) but that did not seem to do anything.
Inject a custom string as Groovy body and call it with csc.newBodyInvoker()
A hacky solution I came up with was just generating the groovy script and running it like the ParallelStep does. But the sandbox does not allow me to call new GroovyShell().evaluate(""), and If I approve that call, the 'stage' step throws a MissingMethodException. So I also do not instatiate the script with the right environment. Providing the EnvironmentExpander does not make any difference.
Referencing and modifying workflow/{n}.xml
Changing the name of a stage in the relevant workflow/{n}.xml and rebooting the server updates the name of the stage, but modifying my custom stage to look like a regular one does not seem to add the step as a stage.
Stuff I've researched:
If some other plugin does something like this, but I couldn't find any example of plugins starting other steps.
How Jenkins handles the scripts and starts the steps, but It seems as though every step is directly called through the method name after the script is parsed, and I found no way to hook into this.
Other plugins using the StageView through other methods, but I could not find any.
add an AtomNode as a head onto the running thread, but I couldn't find how to replace/add the head and am hesitant to mess with jenkins' threading.
I've spent multiple days on this seemingly trivial call, but I can't seem to figure it out.
So the latest thing I tried actually worked, and is displayed correctly, but it ain't pretty.
I basically reimplemented the implementation of DSL.invokeStep(), which required me to use reflection A LOT. This is not safe, and will break with any changes of course so I'll open an issue in the Jenkins' ticket system in the hopes they will add a public interface for doing this. I'm just hoping this won't give me any weird side-effects.
// First, get some environment stuff
CpsThread cpsThread = CpsThread.current();
CpsFlowExecution currentFlowExecution = (CpsFlowExecution) getContext().get(FlowExecution.class);
// instantiate the stage's descriptor
StageStep.DescriptorImpl stageStepDescriptor = new StageStep.DescriptorImpl();
// now we need to put a new FlowNode as the head of the step-stack. This is of course not possible directly,
// but everything is also outside of the sandbox, so putting the class in the same package doesn't work
// get the 'head' field
Field cpsHeadField = CpsThread.class.getDeclaredField("head");
cpsHeadField.setAccessible(true);
Object headValue = cpsHeadField.get(cpsThread);
// get it's value
Method head_get = headValue.getClass().getDeclaredMethod("get");
head_get.setAccessible(true);
FlowNode currentHead = (FlowNode) head_get.invoke(headValue);
// crate a new StepAtomNode starting at the current value of 'head'.
FlowNode an = new StepAtomNode(currentFlowExecution, stageStepDescriptor, currentHead);
// now set this as the new head.
Method head_setNewHead = headValue.getClass().getDeclaredMethod("setNewHead", FlowNode.class);
head_setNewHead.setAccessible(true);
head_setNewHead.invoke(headValue, an);
// Create a new CpsStepContext, and as the constructor is protected, use reflection again
Constructor<?> declaredConstructor = CpsStepContext.class.getDeclaredConstructors()[0];
declaredConstructor.setAccessible(true);
CpsStepContext context = (CpsStepContext) declaredConstructor.newInstance(stageStepDescriptor,cpsThread,currentFlowExecution.getOwner(),an,null);
stageStepDescriptor.checkContextAvailability(context); // Good to check stuff I guess
// Create a new instance of the step, passing in arguments as a Map
Map<String, Object> stageArguments = new HashMap<>();
stageArguments.put("name", "mynutest");
Step stageStep = stageStepDescriptor.newInstance(stageArguments);
// so start the damd thing
StepExecution execution = stageStep.start(context);
// now that we have a callable instance, we set the step on the Cps Thread. Reflection to the rescue
Method mSetStep = cpsThread.getClass().getDeclaredMethod("setStep", StepExecution.class);
mSetStep.setAccessible(true);
mSetStep.invoke(cpsThread, execution);
// Finally. Start running the step
execution.start();
I use this code from the JavaGit example:
File repositoryDirectory = new File("Library\\build\\jar\\");
DotGit dotGit = DotGit.getInstance(repositoryDirectory);
// Print commit messages of the current branch
for (Commit c : dotGit.getLog()) {
System.out.println(c.getMessage());
}
How could I get the id of commit this way?
Or it might be more appropriate library to interact with git?
According to the documentation (I don't know very much this library), you should invoke the getCommitName() method and use the returned Ref object to get the information you want (I think the SHA1 hash or the tag).
I've already been retrieved details of a specific AS/400 job by its job number. I have a problem. I want to get that specific jobs thread detail. Some jobs have multi threading. I need to get specific job's list of multi threads and thread details. I'm checked jt400 doc for finding some class for it. But I'm failing to find :(
Thank in Advance!
JobList jobList = new JobList(System);
jobList.clearJobSelectionCriteria();
jobList.addJobSelectionCriteria(JobList.SELECTION_JOB_NUMBER, jobNumber);
Enumeration list = jobList.getJobs();
while (list.hasMoreElements()) {
Job j = (Job) list.nextElement();
System.out.println(j.getName());
System.out.println(j.getStatus());
System.out.println(j.getOutputQueue());
}
The API you're looking for is QWCOLTHD. JTOpen 8.1 was recently released and I don't see the QWCOLTHD API implemented.
It looks like you either need to email the developers and ask for this API, or write the implementation yourself. JTOpen is open source; you can get the source code and see how similar APIs are implemented and then write the appropriate classes for QWCOLTHD.
How do I merge in JGit?
Let's say I want to merge master with foo branch, how do I do this?
To merge, you can use the MergeCommand (in package org.eclipse.jgit.api), after a CheckoutCommand. To provide you with an example, because indeed Jgit lacks examples:
Git git = ... // you get it through a CloneCommand, InitCommand
// or through the file system
CheckoutCommand coCmd = git.checkout();
// Commands are part of the api module, which include git-like calls
coCmd.setName("master");
coCmd.setCreateBranch(false); // probably not needed, just to make sure
coCmd.call(); // switch to "master" branch
MergeCommand mgCmd = git.merge();
mgCmd.include("foo"); // "foo" is considered as a Ref to a branch
MergeResult res = mgCmd.call(); // actually do the merge
if (res.getMergeStatus().equals(MergeResult.MergeStatus.CONFLICTING)){
System.out.println(res.getConflicts().toString());
// inform the user he has to handle the conflicts
}
I did not try the code so it might not be perfect, but it's just to provide a start. And I didn't include the imports. Developing with JGit implies a lot of tries based on the javadoc
You will find in the JGit repository various test classes for Merge, including for instance the SimpleMergeTest
Merger ourMerger = MergeStrategy.OURS.newMerger(db);
boolean merge = ourMerger.merge(new ObjectId[] { db.resolve("a"), db.resolve("c") });
assertTrue(merge);
Passing an ObjectId is convenient for me, e.g.
void merge(String uri,File file){
try(Git git = Git.cloneRepository()
.setURI(uri)
.setBranch("master")
.setDirectory(file)
.call()){
ObjectId objectId = git.getRepository().resolve("origin/develop");
MergeResult mergeResult = git.merge().include(objectId).call();
log.debug(mergeResult.getMergeStatus());
} catch (GitAPIException | IOException e) {
log.error("error",e);
}
}
furthermore, you can find more examples here: https://github.com/centic9/jgit-cookbook
JGit has a full blown Java implementation of the git resolve merge strategy since 2010. If you need examples look at the corresponding JGit test cases and have a look how EGit is using the MergeCommand, look at class org.eclipse.egit.core.op.MergeOperation.