Permalink
Browse files

feat(bitbucket): bitbucket config integration

  • Loading branch information...
jkuri committed Oct 2, 2017
1 parent b0d1576 commit 14b1af4fbdb63150f05a44509784ca47920ad57c
@@ -21,7 +21,7 @@ describe('Bitbucket repositories', () => {
logout().then(() => browser.waitForAngularEnabled(true));
});

xit('should add bitbucket repository and start new build (send push event)', () => {
it('should add bitbucket repository and start new build (send push event)', () => {
return browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 0);
})
@@ -32,7 +32,9 @@ describe('Bitbucket repositories', () => {
.then(() => browser.get('/repositories'))
.then((): any => isLoaded())
.then((): any => browser.wait(() => element(by.css('.bold')).isPresent()))
.then(() => expect(element.all(by.css('.bold')).last().getText()).to.include('test'))
.then(() => {
expect(element.all(by.css('.bold')).last().getText()).to.eventually.include('test');
})
.then(() => browser.get('/'))
.then((): any => browser.wait(() => {
return element(by.css('.list-item:nth-child(1) .stop-build')).isPresent();
@@ -47,7 +49,7 @@ describe('Bitbucket repositories', () => {
}));
});

xit('should start new build (send reopen_pull_request event)', () => {
it('should start new build (send reopen_pull_request event)', () => {
return sendBitBucketRequest(prReq, headerPullRequestCreated)
.then((): any => browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 1);
@@ -77,7 +79,7 @@ describe('Bitbucket repositories', () => {
}));
});

xit('should restart last build', () => {
it('should restart last build', () => {
return Promise.resolve()
.then((): any => browser.wait(() => {
return element.all(by.css('.disabled')).count().then(cnt => cnt === 0);
@@ -14,7 +14,7 @@ describe('Gitlab repositories', () => {
before(() => login().then(() => browser.waitForAngularEnabled(false)));
after(() => logout().then(() => browser.waitForAngularEnabled(true)));

xit('should add gitlab repository and start new build (send push event)', () => {
it('should add gitlab repository and start new build (send push event)', () => {
return browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 0);
})
@@ -40,7 +40,7 @@ describe('Gitlab repositories', () => {
}));
});

xit('should start new build (send reopen_pull_request event)', () => {
it('should start new build (send reopen_pull_request event)', () => {
return sendGitLabRequest(prReq, prHead)
.then((): any => browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 1);
@@ -70,7 +70,7 @@ describe('Gitlab repositories', () => {
}));
});

xit('should restart last build', () => {
it('should restart last build', () => {
return Promise.resolve()
.then((): any => browser.wait(() => {
return element.all(by.css('.disabled')).count().then(cnt => cnt === 0);
@@ -14,7 +14,7 @@ describe('Gogs repositories', () => {
before(() => login().then(() => browser.waitForAngularEnabled(false)));
after(() => logout().then(() => browser.waitForAngularEnabled(true)));

xit('should add gogs repository and start new build (send push event)', () => {
it('should add gogs repository and start new build (send push event)', () => {
return browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 0);
})
@@ -40,7 +40,7 @@ describe('Gogs repositories', () => {
}));
});

xit('should start new build (send reopen_pull_request event)', () => {
it('should start new build (send reopen_pull_request event)', () => {
return sendGogsRequest(pullRequestOpened, prHead)
.then((): any => browser.wait(() => {
return element.all(by.css('.is-running')).count().then(count => count === 1);
@@ -64,7 +64,7 @@ describe('Gogs repositories', () => {
}));
});

xit('should restart last build', () => {
it('should restart last build', () => {
return Promise.resolve()
.then((): any => browser.wait(() => {
return element.all(by.css('.disabled')).count().then(cnt => cnt === 0);
@@ -60,6 +60,7 @@ export interface Repository {
sha?: string;
file_tree?: string[];
access_token?: string;
type?: 'github' | 'bitbucket' | 'gogs' | 'gitlab';
}

export interface Config {
@@ -87,7 +88,7 @@ export interface Config {
export function getRemoteParsedConfig(repository: Repository): Promise<JobsAndEnv[]> {
return new Promise((resolve, reject) => {
let cloneUrl = repository.clone_url;
let branch = repository.branch;
let branch = repository.type === 'bitbucket' ? 'master' : repository.branch;
let sha = repository.sha || null;
let pr = repository.pr || null;
let cloneDir = null;
@@ -99,7 +100,7 @@ export function getRemoteParsedConfig(repository: Repository): Promise<JobsAndEn
createGitTmpDir()
.then(dir => cloneDir = dir)
.then(() => spawnGit(['clone', cloneUrl, '-b', branch, '--depth', '1', cloneDir]))
.then(() => checkoutShaOrPr(sha, pr, cloneDir))
.then(() => checkoutShaOrPr(sha, pr, cloneDir, repository.type, repository.branch))
.then(() => readGitDir(cloneDir))
.then(files => repository.file_tree = files)
.then(() => {
@@ -400,17 +401,23 @@ export function generateJobsAndEnv(repo: Repository, config: Config): JobsAndEnv
repo.clone_url = repo.clone_url.replace('//', `//${repo.access_token}@`);
}

const clone = `git clone -q ${repo.clone_url} -b ${repo.branch} .`;
let cloneBranch = repo.type === 'bitbucket' ? 'master' : repo.branch;
const clone = `git clone -q ${repo.clone_url} -b ${cloneBranch} .`;

// 2. fetch & checkout
let fetch = null;
let checkout = null;

if (repo.pr) {
fetch = `git fetch origin pull/${repo.pr}/head:pr${repo.pr}`;
checkout = `git checkout pr${repo.pr}`;
if (repo.type === 'github') {
fetch = `git fetch origin pull/${repo.pr}/head:pr${repo.pr}`;
checkout = `git checkout pr${repo.pr}`;
} else if (repo.type === 'bitbucket') {
fetch = `git fetch origin ${repo.branch}:${repo.branch}`;
checkout = `git checkout FETCH_HEAD`;
}
} else if (repo.sha) {
fetch = `git fetch origin`;
fetch = `git fetch origin ${repo.branch}`;
checkout = `git checkout ${repo.sha} .`;
}

@@ -559,17 +566,25 @@ function spawnGit(args: string[]): Promise<void> {
});
}

function checkoutShaOrPr(sha: string, pr: number, dir: string): Promise<void> {
function checkoutShaOrPr(
sha: string, pr: number, dir: string, type: string, branch: string
): Promise<void> {
return new Promise((resolve, reject) => {
let fetch = null;
let checkout = null;
let gitDir = `--git-dir ${dir}/.git`;

if (pr) {
fetch = `${gitDir} fetch origin pull/${pr}/head:pr${pr}`;
checkout = `${gitDir} --work-tree ${dir} checkout pr${pr}`;
if (type === 'github') {
fetch = `${gitDir} fetch origin pull/${pr}/head:pr${pr}`;
checkout = `${gitDir} --work-tree ${dir} checkout pr${pr}`;
} else if (type === 'bitbucket') {
fetch = `${gitDir} fetch origin ${branch}:${branch}`;
checkout = `${gitDir} --work-tree ${dir} checkout FETCH_HEAD`;
}

} else if (sha) {
fetch = `${gitDir} fetch --unshallow`;
fetch = `${gitDir} fetch origin ${branch}`;
checkout = `${gitDir} --work-tree ${dir} checkout ${sha}`;
}

@@ -273,32 +273,31 @@ export function pingBitbucketRepository(data: any): Promise<any> {
return new Promise((resolve, reject) => {
const saveData = generateBitbucketRepositoryData(data);
new Repository().where({ bitbucket_id: saveData.bitbucket_id }).fetch()
.then(repo => {
if (!repo) {
new Repository().save(saveData, { method: 'insert' })
.then(result => {
if (!result) {
reject(result);
} else {
let repository = result.toJSON();
return addRepositoryPermissionToEveryone(result.id)
.then(() => resolve(repository))
.catch(err => reject(err));
}
})
.catch(err => reject(err));
} else {
repo.save(saveData, { method: 'update', require: false })
.then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
.then(repo => {
if (!repo) {
new Repository().save(saveData, { method: 'insert' })
.then(result => {
if (!result) {
reject(result);
} else {
let repository = result.toJSON();
return addRepositoryPermissionToEveryone(result.id)
.then(() => resolve(repository))
.catch(err => reject(err));
}
}).catch(err => reject(err));
} else {
repo.save(saveData, { method: 'update', require: false })
.then(result => {
if (!result) {
reject(result);
} else {
resolve(result.toJSON());
}
})
.catch(err => reject(err));
}
})
.catch(err => reject(err));
}
});
});
});
}

@@ -471,9 +470,7 @@ export function synchronizeBitbucketPullRequest(data: any): Promise<any> {
.then(repository => {
if (!repository) {
const repoData = generateBitbucketRepositoryData(data);
return addRepository(repoData).then(repo => {
repoId = repo.id;
});
return addRepository(repoData).then(repo => repoId = repo.id);
} else {
const repoJson = repository.toJSON();
repoId = repoJson.id;
@@ -585,8 +582,8 @@ function generateGitHubRepositoryData(data: any): any {
}

function generateBitbucketRepositoryData(data: any): any {
const url = new URL(data.repository.clone_url);
const apiUrl = url.protocol + '//' + url.host;
const url = new URL(data.repository.links.self.href);
const apiUrl = url.protocol + '//' + url.host + '/2.0/repositories';

return {
bitbucket_id: data.repository.uuid,
@@ -603,7 +600,6 @@ function generateBitbucketRepositoryData(data: any): any {
user_url: data.actor.links.self.href,
user_html_url: data.actor.links.html.href,
repository_provider: 'bitbucket',
api_url: apiUrl,
data: data
};
}
@@ -436,7 +436,6 @@ export function startBuild(data: any, buildConfig?: any): Promise<any> {
const isGitlab = repository.gitlab_id || false;
const isGogs = repository.gogs_id || false;

// TODO: add other git providers
if (isGithub) {
if (data.data.pull_request) {
pr = data.data.pull_request.number;
@@ -448,6 +447,17 @@ export function startBuild(data: any, buildConfig?: any): Promise<any> {
branch = data.data.ref.split('/').pop();
}
}
} else if (isBitbucket) {
if (data.data.push) {
const push = data.data.push.changes[data.data.push.changes.length - 1];
const commit = push.commits[push.commits.length - 1];
sha = commit.hash;
branch = push.new.type === 'branch' ? push.new.name : 'master';
} else {
pr = data.data.pullrequest.id;
sha = data.data.pullrequest.source.commit.hash;
branch = data.data.pullrequest.source.branch.name;
}
}

branch = branch || repository.default_branch || 'master';
@@ -457,7 +467,8 @@ export function startBuild(data: any, buildConfig?: any): Promise<any> {
branch: branch,
pr: pr,
sha: sha,
access_token: repository.access_token || null
access_token: repository.access_token || null,
type: repository.repository_provider
};

if (buildConfig) {
@@ -66,6 +66,7 @@ <h1 class="bold">
<span *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && build?.data?.sha">{{ build?.data?.sha.slice(0, 7) }}</span>
<span *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && !build?.data?.sha && build?.data?.object_attributes?.last_commit?.id">{{ build?.data?.object_attributes?.last_commit?.id.slice(0, 7) }}</span>
<span *ngIf="build?.data?.push?.changes">{{ build?.data?.push?.changes[0].commits[0].hash.slice(0, 7) }}</span>
<span *ngIf="build?.data?.pullrequest">{{ build?.data?.pullrequest?.source?.commit?.hash.slice(0, 7) }}</span>
</p>
</div>
<div class="column is-4">
@@ -332,6 +332,12 @@ export class AppBuildDetailsComponent implements OnInit, OnDestroy {
this.dateTime = this.build.data.push.changes[0].commits[0].date;
this.committerAvatar = this.build.data.push.changes[0].commits[0].author.user.links.avatar.href;
this.nameCommitter = this.build.data.push.changes[0].commits[0].author.user.display_name;
} else if (this.build.data.pullrequest) {
this.commitMessage = data.pullrequest.description;
this.dateTime = data.pullrequest.updated_on;
this.committerAvatar = data.pullrequest.author.links.avatar.href;
this.nameAuthor = data.pullrequest.author.display_name;
this.nameCommitter = this.nameAuthor;
}

// gitlab
@@ -28,6 +28,7 @@
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && build?.data?.sha">{{ build?.data?.sha }}</span>
<span class="bold" *ngIf="!build?.data?.pull_request?.head?.sha && !build?.data?.after && !build?.data?.sha && build?.data?.object_attributes?.last_commit?.id">{{ build?.data?.object_attributes?.last_commit?.id }}</span>
<span class="bold" *ngIf="build?.data?.push?.changes">{{ build?.data?.push?.changes[0].commits[0].hash }}</span>
<span class="bold" *ngIf="build?.data?.pullrequest">{{ build?.data?.pullrequest?.source?.commit?.hash }}</span>

<span>{{ commitMessage }}</span>

@@ -117,6 +117,10 @@ export class AppBuildItemComponent implements OnInit {
this.commitMessage = this.build.data.push.changes[0].commits[0].message;
this.dateTime = this.build.data.push.changes[0].commits[0].date;
this.committerAvatar = this.build.data.push.changes[0].commits[0].author.user.links.avatar.href;
} else if (this.build.data.pullrequest) {
this.commitMessage = data.pullrequest.description;
this.dateTime = data.pullrequest.updated_on;
this.committerAvatar = data.pullrequest.author.links.avatar.href;
}

// gitlab
@@ -69,6 +69,7 @@ <h2 *ngIf="commitMessage">{{ commitMessage }}</h2>
<span *ngIf="!job?.build?.data?.pull_request && !job?.build?.data?.after && job?.build?.data?.sha">{{ job?.build?.data?.sha.slice(0, 7) }}</span>
<span *ngIf="!job?.build?.data?.pull_request && !job?.build?.data?.after && !job?.build?.data?.sha && job?.build?.data?.object_attributes?.last_commit?.id">{{ job?.build?.data?.object_attributes?.last_commit?.id.slice(0, 7) }}</span>
<span *ngIf="job?.build?.data?.push?.changes">{{ job?.build?.data?.push?.changes[0].commits[0].hash.slice(0, 7) }}</span>
<span *ngIf="job?.build?.data?.pullrequest">{{ job?.build?.data?.pullrequest?.source?.commit?.hash.slice(0, 7) }}</span>
</p>
</div>
<div class="column is-4">
@@ -273,6 +273,12 @@ export class AppJobComponent implements OnInit, OnDestroy {
this.dateTime = this.job.build.data.push.changes[0].commits[0].date;
this.committerAvatar = this.job.build.data.push.changes[0].commits[0].author.user.links.avatar.href;
this.nameCommitter = this.job.build.data.push.changes[0].commits[0].author.user.display_name;
} else if (this.job.build.data.pullrequest) {
this.commitMessage = data.pullrequest.description;
this.dateTime = data.pullrequest.updated_on;
this.committerAvatar = data.pullrequest.author.links.avatar.href;
this.nameAuthor = data.pullrequest.author.display_name;
this.nameCommitter = this.nameAuthor;
}

// gitlab
@@ -0,0 +1,6 @@
require('../helpers/transpile');

const { request, headerPullRequestCreated } = require('../e2e/webhooks/bitbucket/PullRequestEvent');
const { sendBitBucketRequest } = require('../e2e/utils/utils');

sendBitBucketRequest(request, headerPullRequestCreated).then(() => console.log('Done.'));

0 comments on commit 14b1af4

Please sign in to comment.