因为项目需要,需要做一个平台生成代码后, 调用gitlab API 创建项目,并上传代码到gitlab。
在网上搜索了一圈,发现没有这种场景,的确,这种场景也比较少。
先理一下思路,首先平台在指定目前生成特定名称的文件夹,然后调用gitlab接口创建project
公司用的是v4版本,所以url是http://gitlab.XX.com/api/v4/projects?name=test2&path=test2
如果是要指定group ,那把&namespace_id=1 加上即可。
那下面就是需要先在这个文件夹做一个 git init仓库的初始化,然后再去做远程仓库的关联。
但是找一圈网上的jgit的使用,没找到如何去做远程仓库的关联,都是说什么git add remote命令的,既然白嫖不了,那只能是自己看jgit的代码。果然发现有的RemoteSetUrlCommand ,jgit把所有的命令都封装成了XXCommand。使用的方法是调用这个方法,然后填入参数,最后调用call。
/**
* Return a command used to change the URL of an existing remote.
*
* @return a {@link org.eclipse.jgit.api.RemoteSetUrlCommand}
* @since 4.2
*/
public RemoteSetUrlCommand remoteSetUrl() {
return new RemoteSetUrlCommand(repo);
}
具体的写法是
local.remoteSetUrl().setRemoteUri(new URIish(gitUrl)).setRemoteName("origin").call();
看代码以为这很简单,但这个搞了我半天。。。因为少了设置RemoteName,一直设置不成功,只能怪自己没认真看。
但虽然关联成功,调用git.add()的时候报Bare Repository has neither a working tree, nor an index。
结果发现是自己init的时候设置Bare为true.
这个解决后,可以 add 和commit了,但push的时候又报错了
Authentication is required but no CredentialsProvider has been registered
但没看到push的时候可以填这个。
搜了一下源码,发现其实是可以的,只是中间封装了TransportCommand,再次吐血
local.push().setPushAll().setCredentialsProvider(provider).call();
最后完美解决。
同事又提出一个需求说要完成后要新建一个分支,我本来直接放在前面init后面,发现必须先要push后,才能在本地创建新分支。
local.checkout().setCreateBranch(true).setName(branch).call();
local.push().setCredentialsProvider(provider).call();
下面是完整的demo例子,不用谢。
@PostMapping("createProject")
public String createProject(@RequestParam String name, @RequestParam String branch) {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
headers.add("PRIVATE-TOKEN", token);
StringBuffer buffer = new StringBuffer();
buffer.append("?name=");
buffer.append(name);
buffer.append("&path=");
buffer.append(name);
buffer.append("&namespace_id=");
buffer.append(groupId);
//如果项目不存在,则创建项目
String repoUrl = searchProject(name, branch, headers);
if (repoUrl == null) {
HttpEntity httpEntity = new HttpEntity(null, headers);
String url = gitUrl + Project + buffer.toString();
try {
logger.info("url = {}", url);
ResponseEntity<GitlabEntity> response = restTemplate.postForEntity(url, httpEntity, GitlabEntity.class);
logger.info("response {}", response);
if (response != null && response.getStatusCode().equals(HttpStatus.CREATED)) {
GitlabEntity entity = response.getBody();
pushGit(filePath + name, branch, entity.getHttp_url_to_repo());
}
} catch (Exception e) {
logger.error("project create fail e {} ", e);
}
} else {
//项目已存在,则需要新建branch
pushGit(filePath + name, branch, repoUrl);
}
return "success";
}
private String searchProject(String name, String branch, HttpHeaders httpHeaders) {
HttpEntity httpEntity = new HttpEntity(null, httpHeaders);
String url1 = gitUrl + Project + "?search=" + name;
logger.info("url = {}", url1);
ResponseEntity<List> response = restTemplate.exchange(url1, HttpMethod.GET, httpEntity, List.class);
if (response != null && response.getStatusCode().equals(HttpStatus.OK)) {
List<Map<String, Object>> o = response.getBody();
logger.info("body = {}", response.getBody());
if (o.size() > 0) {
Map<String, Object> project = o.get(0);
if (!checkBranch(project.get("id"), branch, httpHeaders)) {
throw new RuntimeException("branch exits");
}
logger.error("项目已存在");
return project.get("http_url_to_repo").toString();
}
}
return null;
}
private boolean checkBranch(Object id, String branch, HttpHeaders httpHeaders) {
HttpEntity httpEntity = new HttpEntity(null, httpHeaders);
///projects/:id/repository/branches/:branch
String url = gitUrl + Project + "/" + id + BRANCHS + branch;
logger.info("branch = {}", url);
try {
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, httpEntity, Map.class);
if (response != null && response.getStatusCode().equals(HttpStatus.OK)) {
// List<Map<String,Object>> o = response.getBody();
logger.info("body = {}", response.getBody());
if (response.getBody() != null) {
logger.error("branch 已存在");
return false;
}
}
} catch (Exception e) {
logger.info("check branch fail id {} branch {}",id,branch);
}
return true;
}
private boolean pushGit(String name, String branch, String gitUrl) {
Git init;
try {
init = GitUtil.init(new File(name));
} catch (GitAPIException e) {
logger.info("git init fail e {}", e);
return false;
}
try {
Git local = Git.open(init.getRepository().getDirectory());
local.remoteSetUrl().setRemoteUri(new URIish(gitUrl)).setRemoteName("origin").call();
local.add().addFilepattern(".").call();
local.commit().setMessage("update").call();
local.push().setPushAll().setCredentialsProvider(provider).call();
// new branch
local.checkout().setCreateBranch(true).setName(branch).call();
local.push().setCredentialsProvider(provider).call();
} catch (IOException | URISyntaxException | GitAPIException e) {
logger.info("git open fail e {}", e);
return false;
}
return true;
}