Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: #132 支持公共库 #133

Merged
merged 1 commit into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion internal/api/integrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package api

import (
"reflect"

"github.com/go-atomci/atomci/constant"

"github.com/go-atomci/atomci/internal/core/settings"
Expand Down Expand Up @@ -77,12 +79,23 @@ func (p *IntegrateController) GetSCMIntegrateSettings() {
}
// for security hidden config content
for _, item := range rsp {
item.IntegrateSettingReq.Config = nil
//用于前端生成完成仓库地址
item.IntegrateSettingReq.Config = settings.BaseConfig{
URL: getBaseConfigUrl(item.IntegrateSettingReq.Config),
}
}
p.Data["json"] = NewResult(true, rsp, "")
p.ServeJSON()
}

// 获取仓库域名
// TODO现在用反射获取,有更好方法再替换
func getBaseConfigUrl(config interface{}) string {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

将interface{}变更为强类型,或者接口?这样更OO

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

config是 interface{} 是由 pm.GetIntegrateSettings返回定义好的

immutable := reflect.ValueOf(config).Elem()
url := immutable.FieldByName("URL").String()
return url
}

// GetSCMIntegrateSettingsByPagination ..
func (p *IntegrateController) GetSCMIntegrateSettingsByPagination() {
filterQuery := p.GetFilterQuery()
Expand Down
52 changes: 24 additions & 28 deletions internal/core/apps/gitapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ package apps
import (
"context"
"fmt"
"github.com/drone/go-scm/scm/driver/gogs"
"net/http"
"strings"

"github.com/drone/go-scm/scm/driver/gogs"

"github.com/drone/go-scm/scm/driver/gitea"

"github.com/go-atomci/atomci/internal/middleware/log"
Expand Down Expand Up @@ -59,49 +60,44 @@ func NewScmProvider(vcsType, vcsPath, token string) (*scm.Client, error) {

if "gitea" == gitRepo {
client, err = gitea.New(schema + "://" + projectPathSplit[0])
client.Client = &http.Client{
Transport: &transport.BearerToken{
Token: token,
},
}
} else if "gitlab" == gitRepo {
client, err = gitlab.New(schema + "://" + projectPathSplit[0])

client.Client = &http.Client{
Transport: &transport.PrivateToken{
Token: token,
},
}
} else {
client, err = gogs.New(schema + "://" + projectPathSplit[0])
client.Client = &http.Client{
Transport: &transport.PrivateToken{
Token: token,
},
}
}
case "github":
client = github.NewDefault()

client.Client = &http.Client{
Transport: &transport.BearerToken{
Token: token,
},
}

case "gitee":
client = gitee.NewDefault()
default:
err = fmt.Errorf("source code management system not configured")
}
if client != nil {
client.Client = getSCMHttpClient(vcsType, token)
}
return client, err
}

client.Client = &http.Client{
// 根据不同类型获取客户端,若有token,则配置对应token;无token,表示公共库,不配置鉴权信息
func getSCMHttpClient(scmType string, token string) *http.Client {
if token == "" {
return &http.Client{}
}
switch strings.ToLower(scmType) {
case "gitlab", "gogs":
return &http.Client{
Transport: &transport.PrivateToken{
Token: token,
}}
case "gitea", "gitee", "github":
return &http.Client{
Transport: &transport.BearerToken{
Token: token,
},
}

default:
err = fmt.Errorf("source code management system not configured")
return nil
}
return client, err
}

// SyncAppBranches ...
Expand Down
4 changes: 4 additions & 0 deletions internal/core/apps/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ func (manager *AppManager) GetScmProjectsByRepoID(repoID int64) (interface{}, er
if err != nil {
return nil, err
}
// 获取仓库项目需要授权,若配置的仓库是公共库,则直接返回
if scmIntegrateResp.ScmAuthConf.Token == "" {
return []*RepoProjectRsp{}, nil
}
scmClient, err := NewScmProvider(scmIntegrateResp.Type, scmIntegrateResp.ScmAuthConf.URL, scmIntegrateResp.ScmAuthConf.Token)
if err != nil {
log.Log.Error("init scm Client occur error: %v", err.Error())
Expand Down
104 changes: 80 additions & 24 deletions web/src/views/scmapp/components/AppAdd.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
>
<div class="arrange-body">
<template>
<el-form ref="ruleForm" :model="form" :rules="rules">
<el-form ref="ruleForm" :model="form" :rules="rules" label-width="100px" >
<el-form-item label="代码源" prop="repo_id">
<el-select
v-model="form.repo_id"
Expand All @@ -51,25 +51,25 @@
</el-select>
</el-form-item>

<el-form-item label="仓库地址" prop="path">
<el-select
v-model="form.path"
filterable
placeholder="请选择语言类型"
<el-form-item label="仓库路径" prop="full_name">
<el-autocomplete
v-model="form.full_name"
style="width: 300px"
@change="setScmAppName()"
>
<el-option
v-for="(item, index) in scmProjects"
:key="index"
:label="item.full_name"
:value="item.path"
>
</el-option>
</el-select>
placeholder="请选择/输入路径"
:fetch-suggestions="querySearch"
@blur="setScmAppName"
@select="setSelectPath">
<i
class="el-icon-edit el-input__icon"
slot="suffix">
</i>
<template slot-scope="{ item }">
<div class="name">{{ item.full_name }}</div>
</template>
</el-autocomplete>
</el-form-item>

<el-form-item label="应用名" prop="build_path">
<el-form-item label="应用名" prop="name">
<el-input
v-model="form.name"
placeholder="请输入应用名"
Expand Down Expand Up @@ -172,9 +172,11 @@ export default {
},
getRepoLoading: true,
rules: {
name: [{ required: true, message: '请输入应用名', trigger: 'blur' }],
type: [{ required: true, message: '请选择应用类型', trigger: 'change' }],
repo_id: [{ required: true, message: '请选择代码源', trigger: 'change' }],
path: [{ required: true, message: '请选择仓库地址', trigger: 'change' }],
full_name: [{ required: true, message: '请选择/输入仓库路径', trigger: 'blur' }],
compile_env_id: [{ required: false, message: '请选择应用编译环境', trigger: 'change' }],
language: [{ required: true, message: '请选择语言类型', trigger: 'change' }],
},
Expand All @@ -196,18 +198,59 @@ export default {
this.getIntegrateRepos();
},
methods: {
setScmAppName() {
if (this.form.path == undefined) {
return
}
querySearch(queryString, cb) {
var scmProjects = this.scmProjects;
var results = queryString ? scmProjects.filter(this.createFilter(queryString)) : scmProjects;
// 调用 callback 返回建议列表的数据
cb(results);
},
createFilter(queryString) {
return (scmProjects) => {
return (scmProjects.full_name.toLowerCase().indexOf(queryString.toLowerCase()) === 0);
};
},
setSelectPath(item){
this.form.full_name=item.full_name;
for (let i = 0; i < this.scmProjects.length; i++) {
if (this.scmProjects[i].path == this.form.path) {
this.form.name = this.scmProjects[i].name
this.form.full_name = this.scmProjects[i].full_name
if (this.scmProjects[i].full_name == this.form.full_name) {
this.form.name = this.scmProjects[i].name;
this.form.path = this.scmProjects[i].path;
break
}
}
},
setScmAppName() {
this.setFullName();
if (this.form.full_name && !this.form.name) {
let names = this.form.full_name.split('/');
this.form.name = names[names.length-1].split('.')[0]
}
this.form.path = "";
for (let i = 0; i < this.scmProjects.length; i++) {
if (this.scmProjects[i].full_name == this.form.full_name) {
this.form.path = this.scmProjects[i].path;
return
}
}
},
setFullName(){
if (!this.form.full_name){
return;
}
let fullName=this.form.full_name;
// 优化路径,路径只需要[域名]和[.git]之间部分就行
// 若是完整路径,如 http://reap.com/xx.git,则去除域名
if(fullName.toLowerCase().indexOf('http://') > -1 || fullName.toLowerCase().indexOf('https://') > -1){
let index = this.form.full_name.indexOf('/',8);
fullName = this.form.full_name.substring(index + 1);
}
// 若路径包含[.git],也要去掉
if(fullName.length > 3 && fullName.substring(fullName.length - 4).toLowerCase() == '.git'){
this.form.full_name = fullName.substring(0,fullName.length - 4);
return
}
this.form.full_name = fullName;
},
getIntegrateRepos() {
backend.getIntegrateRepos((data) => {
if (data) {
Expand Down Expand Up @@ -245,6 +288,19 @@ export default {
addApp() {
this.$refs.ruleForm.validate((valid) => {
if (valid) {
// 完整的路径地址不存在的话,则组装一个出来
if(this.form.path==""){
for (let i = 0; i < this.integrateRepos.length; i++) {
if (this.integrateRepos[i].id == this.form.repo_id) {
let domain= this.integrateRepos[i].config.url;
if(domain && domain.length>0 && domain.substring(domain.length-1)=='/'){
this.form.path = domain + this.form.full_name + '.git';
}else {
this.form.path = domain + '/' + this.form.full_name + '.git';
}
}
}
}
const cl = this.form
cl.type = 'app';
cl.dockerfile = this.form.dockerfile || 'Dockerfile';
Expand Down
17 changes: 15 additions & 2 deletions web/src/views/setting/components/ScmIntegrateCreate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -27,17 +27,23 @@
</el-option>
</el-select>
</el-form-item>
<div>
<el-form-item label="仓库类型" class="form-item" >
<el-radio v-model="repoType" label="0">私有</el-radio>
<el-radio v-model="repoType" label="1">开源</el-radio>
</el-form-item>
</div>
<div>
<el-form-item label="地址" prop="config.url" class="form-item" >
<el-input v-model="form.config.url" auto-complete="off" :disabled="disabledEditURL" placeholder="请输入代码源地址"></el-input>
</el-form-item>
</div>
<div v-if="form.type ==='gitlab'">
<div v-if="repoType === '0' && form.type ==='gitlab'">
<el-form-item label="用户名" prop="config.user" class="form-item">
<el-input v-model.trim="form.config.user" auto-complete="off" placeholder="请输入gitlab用户名"></el-input>
</el-form-item>
</div>
<div>
<div v-if="repoType === '0'">
<el-form-item label="Token" prop="config.token" class="form-item">
<el-input v-model.trim="form.config.token" auto-complete="off" maxlength="120" placeholder="请输入代码源Token"></el-input>
</el-form-item>
Expand Down Expand Up @@ -76,6 +82,7 @@ export default {
data() {
return {
name: '',
repoType:"0",
disabledEditURL: false,
groupRoleList: [],
settingTypeList: [
Expand Down Expand Up @@ -149,6 +156,7 @@ export default {
this.isEdit = flag;
if (flag) {
this.title = '编辑配置';
this.repoType = item.config.token ? "0" : "1";
this.form = {
name: item.name || '',
type: item.type || '',
Expand Down Expand Up @@ -189,6 +197,11 @@ export default {
type: this.form.type,
description: this.form.description,
};
if (this.repoType == '1'){
cl.config={
url:this.form.config.url
}
}
if (this.isEdit) {
backend.editIntegrateSetting(this.rowId, cl, () => {
successCallBack();
Expand Down