Skip to content

Commit e759e4f

Browse files
committed
add branch listing suggestions
1 parent 058fd4f commit e759e4f

File tree

11 files changed

+181
-20
lines changed

11 files changed

+181
-20
lines changed

CONTRIBUTING.md

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
All contributions are welcome. For simple typos, just open a PR.
44
For bigger ideas it might be better to open a issue first before you put a lot of work into it.
55

6+
Want to contribute, but dont know where to start? Have a look into the Roadmap.
7+
68
## Development setup
79
### Requirements
810
- docker

client/src/components/apps/new.vue

+23-11
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@
5858
<v-text-field
5959
v-model="pipelineData.git.repository.ssh_url"
6060
:rules="repositoryRules"
61-
:counter="60"
6261
label="Repository"
6362
required
6463
disabled
@@ -71,13 +70,12 @@
7170
cols="12"
7271
md="6"
7372
>
74-
<v-text-field
73+
<v-combobox
7574
v-model="branch"
76-
:rules="branchRules"
77-
:counter="60"
75+
:items="branchesList"
7876
label="Branch"
7977
required
80-
></v-text-field>
78+
></v-combobox>
8179
</v-col>
8280
</v-row>
8381
<v-row
@@ -116,7 +114,6 @@
116114
>
117115
<v-text-field
118116
v-model="docker.tag"
119-
:rules="branchRules"
120117
:counter="60"
121118
label="Tag"
122119
required
@@ -507,6 +504,7 @@ export default {
507504
ssh_url: '[email protected]:kubero-dev/template-nodeapp.git',
508505
},
509506
branch: 'main',
507+
branchesList: [],
510508
docker: {
511509
image: 'ghcr.io/kubero-dev/template-nodeapp',
512510
tag: 'main',
@@ -563,11 +561,6 @@ export default {
563561
// ((git|ssh|http(s)?)|(git@[\w\.]+))(:(//)?)([\w\.@\:/\-~]+)(\.git)(/)?
564562
v => /((git|ssh|http(s)?)|(git@[\w.]+))(:(\/\/)?)([\w.@:/\-~]+)(\.git)(\/)?/.test(v) || 'Format "owner/repository"',
565563
],
566-
branchRules: [
567-
//v => !!v || 'Branch is required',
568-
v => v.length <= 60 || 'Name must be less than 60 characters',
569-
v => /^[a-zA-Z0-9][a-zA-Z0-9_-]*$/.test(v) || 'Allowed characters : [a-zA-Z0-9_-]',
570-
],
571564
domainRules: [
572565
v => !!v || 'Domain is required',
573566
v => v.length <= 60 || 'Name must be less than 60 characters',
@@ -605,6 +598,8 @@ export default {
605598
this.buildpack = this.pipelineData.buildpack;
606599
607600
this.gitrepo.ssh_url = this.pipelineData.git.repository.ssh_url;
601+
602+
this.loadBranches();
608603
/*
609604
if (this.app == 'new') {
610605
switch (this.pipelineData.github.repository.language) {
@@ -623,6 +618,23 @@ export default {
623618
*/
624619
});
625620
},
621+
loadBranches() {
622+
623+
// encode string to base64 (for ssh url)
624+
const gitrepoB64 = btoa(this.pipelineData.git.repository.ssh_url);
625+
const gitprovider = this.pipelineData.git.provider;
626+
627+
axios.get('/api/repo/'+gitprovider+"/"+gitrepoB64+"/branches/list").then(response => {
628+
for (let i = 0; i < response.data.length; i++) {
629+
this.branchesList.push({
630+
text: response.data[i],
631+
value: response.data[i],
632+
});
633+
}
634+
});
635+
},
636+
637+
626638
loadPodsizeList() {
627639
axios.get('/api/config/podsize').then(response => {
628640
for (let i = 0; i < response.data.length; i++) {

client/src/components/pipelines/new.vue

+2
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ export default {
188188
keys: {},
189189
repository: {},
190190
webhooks: {},
191+
provider: ""
191192
},
192193
repository_status: {
193194
error: false,
@@ -379,6 +380,7 @@ export default {
379380
this.repository_status.connected = false;
380381
this.repository_status.statusTxt = "Repository Not Connected";
381382
}
383+
this.git.provider = this.repotab;
382384
383385
}).catch(error => {
384386
console.log(error);

src/git/bitbucket.ts

+22
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,26 @@ export class BitbucketApi extends Repo {
285285
}
286286
return ret;
287287
}
288+
289+
public async getBranches(gitrepo: string): Promise<string[]> {
290+
//https://bitbucketjs.netlify.app/#api-repositories-repositories_listBranches
291+
292+
let repo = "template-nodeapp"
293+
let owner = "gicara"
294+
try {
295+
const branches = await this.bitbucket.repositories.listBranches({
296+
repo_slug: repo,
297+
workspace: owner,
298+
sort: '-name'
299+
})
300+
if (branches.data.values != undefined) {
301+
return branches.data.values.map((branch: any) => branch.name);
302+
}
303+
} catch (error) {
304+
debug.log(error)
305+
}
306+
307+
return [];
308+
309+
}
288310
}

src/git/gitea.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ export class GiteaApi extends Repo {
171171
if (key.title === title &&
172172
key.read_only === true) {
173173
ret = {
174-
status: 422,
174+
status: 200,
175175
statusText: 'found',
176176
data: key,
177177
}
@@ -274,4 +274,24 @@ export class GiteaApi extends Repo {
274274
}
275275
return ret;
276276
}
277+
278+
public async getBranches(gitrepo: string): Promise<string[]>{
279+
// https://try.gitea.io/api/swagger#/repository/repoListBranches
280+
let ret: string[] = [];
281+
282+
//let repo = "template-nodeapp"
283+
//let owner = "gicara"
284+
285+
let {repo, owner} = this.parseRepo(gitrepo)
286+
try {
287+
const branches = await this.gitea.repos.repoListBranches(owner, repo)
288+
for (let branch of branches.data) {
289+
ret.push(branch.name)
290+
}
291+
} catch (error) {
292+
console.log(error)
293+
}
294+
295+
return ret;
296+
}
277297
}

src/git/github.ts

+23-7
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export class GithubApi extends Repo {
3030
}
3131
}
3232

33-
// TODO : Improve matching here
33+
// TODO : Improve matching here or use default function in Superclass
3434
let owner = gitrepo.match(/^git@github.com:(.*)\/.*$/)?.[1] as string;
3535
let repo = gitrepo.match(/^git@github.com:.*\/(.*).git$/)?.[1] as string;
3636

@@ -84,12 +84,6 @@ export class GithubApi extends Repo {
8484
}
8585

8686
/*
87-
public async getRepositoryBranches(owner: string, repo: string) {
88-
return await this.octokit.git.listBranches({
89-
owner: owner,
90-
repo: repo
91-
});
92-
}
9387
9488
public async getRepositoryCommits(owner: string, repo: string, branch: string) {
9589
return await this.octokit.git.listCommits({
@@ -290,4 +284,26 @@ export class GithubApi extends Repo {
290284
}
291285
return ret;
292286
}
287+
288+
public async getBranches(gitrepo: string): Promise<string[]>{
289+
290+
let ret: string[] = [];
291+
292+
let repo = "template-nodeapp"
293+
let owner = "kubero-dev"
294+
try {
295+
const branches = await this.octokit.request('GET /repos/{owner}/{repo}/branches', {
296+
owner: owner,
297+
repo: repo,
298+
})
299+
for (let branch of branches.data) {
300+
ret.push(branch.name)
301+
}
302+
} catch (error) {
303+
debug.log(error)
304+
}
305+
306+
return ret;
307+
308+
}
293309
}

src/git/gitlab.ts

+25
Original file line numberDiff line numberDiff line change
@@ -307,4 +307,29 @@ export class GitlabApi extends Repo {
307307
return ret;
308308
}
309309

310+
public async getBranches(gitrepo: string): Promise<string[]>{
311+
// https://docs.gitlab.com/ee/api/branches.html#list-repository-branches
312+
// not implemented yet
313+
let ret: string[] = [];
314+
315+
let repo = "template-nodeapp"
316+
let owner = "gicara"
317+
try {
318+
const branches:any = await this.gitlab.get(`projects/${owner}%2F${repo}/repository/branches`)
319+
.catch((error: any) => {
320+
console.log(error)
321+
return ret;
322+
})
323+
324+
for (let branch of branches) {
325+
ret.push(branch.name)
326+
}
327+
} catch (error) {
328+
console.log(error)
329+
}
330+
331+
332+
return ret;
333+
}
334+
310335
}

src/git/gogs.ts

+18-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,6 @@ export class GogsApi extends Repo {
209209
}
210210

211211
public getWebhook(event: string, delivery: string, signature: string, body: any): IWebhook | boolean {
212-
//https://docs.github.com/en/developers/webhooks-and-events/webhooks/securing-your-webhooks
213212
let secret = process.env.KUBERO_WEBHOOK_SECRET as string;
214213
let hash = 'sha256='+crypto.createHmac('sha256', secret).update(JSON.stringify(body, null, ' ')).digest('hex')
215214

@@ -274,4 +273,22 @@ export class GogsApi extends Repo {
274273
}
275274
return ret;
276275
}
276+
277+
public async getBranches(gitrepo: string): Promise<string[]>{
278+
// https://try.gitea.io/api/swagger#/repository/repoListBranches
279+
let ret: string[] = [];
280+
281+
let repo = "template-nodeapp"
282+
let owner = "gicara"
283+
try {
284+
const branches = await this.gitea.repos.repoListBranches(owner, repo)
285+
for (let branch of branches.data) {
286+
ret.push(branch.name)
287+
}
288+
} catch (error) {
289+
console.log(error)
290+
}
291+
292+
return ret;
293+
}
277294
}

src/git/repo.ts

+7
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,15 @@ export abstract class Repo {
106106

107107
}
108108

109+
protected parseRepo(gitrepo: string): {owner: string, repo: string} {
110+
let owner = gitrepo.match(/^git@.*:(.*)\/.*$/)?.[1] as string;
111+
let repo = gitrepo.match(/^git@.*:.*\/(.*).git$/)?.[1] as string;
112+
return { owner: owner, repo: repo };
113+
}
114+
109115
protected abstract addDeployKey(owner: string, repo: string): Promise<IDeploykeyR>
110116
protected abstract getRepository(gitrepo: string): Promise<IRepository>;
111117
protected abstract addWebhook(owner: string, repo: string, url: string, secret: string): Promise<IWebhookR>;
112118
protected abstract getWebhook(event: string, delivery: string, signature: string, body: any): IWebhook | boolean;
119+
protected abstract getBranches(repo: string): Promise<string[]> | undefined;
113120
}

src/kubero.ts

+32
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,38 @@ export class Kubero {
398398
}
399399
}
400400

401+
public async listRepoBranches(repoProvider: string, repoB64: string ): Promise<string[]> {
402+
//return this.git.listRepoBranches(repo, repoProvider);
403+
let branches: Promise<string[]> = new Promise((resolve, reject) => {
404+
resolve([]);
405+
});
406+
407+
const repo = Buffer.from(repoB64, 'base64').toString('ascii');
408+
409+
switch (repoProvider) {
410+
case 'github':
411+
branches = this.githubApi.getBranches(repo);
412+
break;
413+
case 'gitea':
414+
branches = this.giteaApi.getBranches(repo);
415+
break;
416+
case 'gogs':
417+
branches = this.gogsApi.getBranches(repo);
418+
break;
419+
case 'gitlab':
420+
branches = this.gitlabApi.getBranches(repo);
421+
break;
422+
case 'bitbucket':
423+
branches = this.bitbucketApi.getBranches(repo);
424+
break;
425+
case 'ondev':
426+
default:
427+
break;
428+
}
429+
430+
return branches
431+
}
432+
401433
private async getAppsByBranch(branch: string) {
402434
debug.log('getAppsByBranch: '+branch);
403435
let apps: IApp[] = [];

src/routes/repo.ts

+6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ Router.post('/repo/:repoprovider/connect', async function (req: Request, res: Re
1919
res.send(con);
2020
});
2121

22+
// connect pipeline with repository
23+
Router.get('/repo/:repoprovider/:gitrepob64/branches/list', async function (req: Request, res: Response) {
24+
let branches = await req.app.locals.kubero.listRepoBranches(req.params.repoprovider, req.params.gitrepob64);
25+
res.send(branches);
26+
});
27+
2228
// get github webhook events
2329
Router.all('/repo/webhooks/:repoprovider', async function (req: Request, res: Response) {
2430

0 commit comments

Comments
 (0)