Repository: kubesphere/ks-devops
Pull request #520 (2022-03-29 01:49:32)

Support to fetch repositories from a user account
<!-- Thanks for sending a pull request! Here are some tips for you:

1. If you want **faster** PR reviews, read how: https://github.com/kubesphere/community/blob/master/developer-guide/development/the-pr-author-guide-to-getting-through-code-review.md
2. In case you want to know how your PR got reviewed, read: https://github.com/kubesphere/community/blob/master/developer-guide/development/code-review-guide.md
3. Here are some coding conventions followed by the KubeSphere community: https://github.com/kubesphere/community/blob/master/developer-guide/development/coding-conventions.md
4. Additional open-source best practice: https://github.com/LinuxSuRen/open-source-best-practice
-->

### What type of PR is this?
<!-- 
Add one of the following kinds:
/kind bug
/kind cleanup
/kind documentation
/kind feature
/kind design
/kind chore

Optionally add one or more of the following kinds if applicable:
/kind api-change
/kind deprecation
/kind failing-test
/kind flake
/kind regression
-->

### What this PR does / why we need it:
/kind feature

* The `drone/go-scm` has fewer features than `jenkins-x/go-scm`. So, I made the changes.
* The second, add support to fetch the repositories from both the organization and user account

Please feel free to use the following image if you want to help to test this PR:

```
kubespheredev/devops-apiserver:dev-v3.2.1-c75f603
```

### Which issue(s) this PR fixes:
<!--
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
Please leave it or change # to be None if there is no corresponding issue that exists
-->
Fixes #

### Special notes for reviewers:
<!--
You can use the following command to let the DevOps SIG members help you to review your PR.
/cc @kubesphere/sig-devops 
And please avoid cc any individual.
-->
Please check the following list before waiting reviewers:

- [ ] Already committed the CRD files to [the Helm Chart](https://github.com/kubesphere-sigs/ks-devops-helm-chart/) if you created some new CRDs
- [ ] Already [added the permission](https://github.com/kubesphere/ks-installer/blob/9e063b085a0e43fdb3d0d9e3e7f4149146f14b9c/roles/ks-core/prepare/files/ks-init/role-templates.yaml) for the new API
- [ ] Already added the RBAC markers for the new controllers

### Does this PR introduce a user-facing change??
<!--
If no, just write "None" in the release-note block below.
If yes, a release note is required:
Enter your extended-release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".

Please keep the note be same as your PR title if you believe it should be in the release notes.
-->
```release-note
None
```


ks-ci-bot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/kubesphere/ks-devops/pull/520#" title="Author self-approved">LinuxSuRen</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=kubesphere%2Fks-devops).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[OWNERS](https://github.com/kubesphere/ks-devops/blob/master/OWNERS)~~ [LinuxSuRen]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) Report
> Merging [#520](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) (c75f603) into [master](https://codecov.io/gh/kubesphere/ks-devops/commit/2ca3766ffe262284ea8405c0f853eca52394c3be?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) (2ca3766) will **increase** coverage by `0.04%`.
> The diff coverage is `82.92%`.

```diff
@@            Coverage Diff             @@
##           master     #520      +/-   ##
==========================================
+ Coverage   77.39%   77.43%   +0.04%     
==========================================
  Files         140      140              
  Lines       22952    22969      +17     
==========================================
+ Hits        17764    17787      +23     
+ Misses       4991     4984       -7     
- Partials      197      198       +1     
```

| Flag | Coverage Δ | |
|---|---|---|
| unittests | `77.43% <82.92%> (+0.04%)` | :arrow_up: |

Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#carryforward-flags-in-the-pull-request-comment) to find out more.

| [Impacted Files](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere) | Coverage Δ | |
|---|---|---|
| [.../gitrepository/gitrepository\_webhook\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvZ2l0cmVwb3NpdG9yeS9naXRyZXBvc2l0b3J5X3dlYmhvb2tfY29udHJvbGxlci5nbw==) | `50.83% <0.00%> (ø)` | |
| [pkg/kapis/devops/v1alpha3/scm/scmhandler.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2thcGlzL2Rldm9wcy92MWFscGhhMy9zY20vc2NtaGFuZGxlci5nbw==) | `81.17% <81.48%> (-1.69%)` | :arrow_down: |
| [pkg/client/git/client.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2NsaWVudC9naXQvY2xpZW50Lmdv) | `100.00% <100.00%> (ø)` | |
| [pkg/kapis/devops/v1alpha3/scm/route.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-cGtnL2thcGlzL2Rldm9wcy92MWFscGhhMy9zY20vcm91dGUuZ28=) | `100.00% <100.00%> (ø)` | |
| [...ns/devopscredential/devopscredential\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvamVua2lucy9kZXZvcHNjcmVkZW50aWFsL2Rldm9wc2NyZWRlbnRpYWxfY29udHJvbGxlci5nbw==) | `36.73% <0.00%> (+3.40%)` | :arrow_up: |
| [...ontrollers/jenkins/pipeline/pipeline\_controller.go](https://codecov.io/gh/kubesphere/ks-devops/pull/520/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere#diff-Y29udHJvbGxlcnMvamVua2lucy9waXBlbGluZS9waXBlbGluZV9jb250cm9sbGVyLmdv) | `43.18% <0.00%> (+3.78%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere). Last update [2ca3766...c75f603](https://codecov.io/gh/kubesphere/ks-devops/pull/520?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=kubesphere).


Patch:
diff --git a/config/samples/secret.yaml b/config/samples/secret.yaml
new file mode 100644
index 0000000..de8ad54
--- /dev/null
+++ b/config/samples/secret.yaml
@@ -0,0 +1,8 @@
+apiVersion: v1
+stringData:
+  username: linuxsuren
+  password: linuxsuren
+kind: Secret
+metadata:
+  name: github
+type: credential.devops.kubesphere.io/basic-auth
diff --git a/controllers/gitrepository/gitrepository_webhook_controller.go b/controllers/gitrepository/gitrepository_webhook_controller.go
index e677ef9..5758be8 100644
--- a/controllers/gitrepository/gitrepository_webhook_controller.go
+++ b/controllers/gitrepository/gitrepository_webhook_controller.go
@@ -16,7 +16,7 @@ package gitrepository
 import (
 	"context"
 	"fmt"
-	"github.com/drone/go-scm/scm"
+	"github.com/jenkins-x/go-scm/scm"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/types"
 	"kubesphere.io/devops/pkg/api/devops/v1alpha3"
@@ -128,9 +128,9 @@ func (r *Reconciler) createOrUpdateWebhook(repo *v1alpha3.GitRepository) (err er
 			NativeEvents: webhook.Spec.Events,
 		}
 
-		if ok, id := exist(webhook.Spec.Server, hooks); ok {
+		if ok, _ := exist(webhook.Spec.Server, hooks); ok {
 			// update the existing webhooks
-			_, _, err = gitClient.Repositories.UpdateHook(context.TODO(), repoAddress, id, hookInput)
+			_, _, err = gitClient.Repositories.UpdateHook(context.TODO(), repoAddress, hookInput)
 		} else {
 			// create the webhook
 			_, _, err = gitClient.Repositories.CreateHook(context.TODO(), repoAddress, hookInput)
diff --git a/go.mod b/go.mod
index 73cca6e..8d98564 100644
--- a/go.mod
+++ b/go.mod
@@ -9,7 +9,6 @@ require (
 	github.com/aws/aws-sdk-go v1.38.52
 	github.com/beevik/etree v1.1.0
 	github.com/davecgh/go-spew v1.1.1
-	github.com/drone/go-scm v1.16.2
 	github.com/emicklei/go-restful v2.9.6+incompatible
 	github.com/emicklei/go-restful-openapi v1.4.1
 	github.com/emicklei/go-restful-swagger12 v0.0.0-20201014110547-68ccff494617
@@ -25,6 +24,7 @@ require (
 	github.com/google/go-cmp v0.5.5
 	github.com/google/go-querystring v1.1.0 // indirect
 	github.com/h2non/gock v1.0.9
+	github.com/jenkins-x/go-scm v1.11.4
 	github.com/jenkins-zh/jenkins-client v0.0.9
 	github.com/kubesphere/sonargo v0.0.2
 	github.com/onsi/ginkgo v1.16.4
diff --git a/go.sum b/go.sum
index 4f6eeaa..145aec2 100644
--- a/go.sum
+++ b/go.sum
@@ -12,6 +12,7 @@ cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2k
 cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
 code.cloudfoundry.org/bytefmt v0.0.0-20210524144015-27119551aaea h1:sgtgFDWrhV2cML3UbS2EZu+AfHLP96N0DJ1IHqI1rXA=
 code.cloudfoundry.org/bytefmt v0.0.0-20210524144015-27119551aaea/go.mod h1:yABoJ2k296jrOM76JpOlcsbJuC/4d+WtP+MEAQuuQOk=
+code.gitea.io/sdk/gitea v0.14.0/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
 dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
 github.com/AlecAivazis/survey/v2 v2.2.12/go.mod h1:6d4saEvBsfSHXeN1a5OA5m2+HJ2LuVokllnC77pAIKI=
@@ -71,6 +72,7 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB
 github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
 github.com/blang/semver v3.5.0+incompatible h1:CGxCgetQ64DKk7rdZ++Vfnb1+ogGNnB17OJKJXD2Cfs=
 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/bluekeyes/go-gitdiff v0.4.0/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/chai2010/gettext-go v0.0.0-20170215093142-bf70f2a70fb1/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
@@ -105,8 +107,6 @@ github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDD
 github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
 github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
-github.com/drone/go-scm v1.16.2 h1:IoxgyIACUArg3d7US8OR1Vwsph3U/x7imNTU5QK47C4=
-github.com/drone/go-scm v1.16.2/go.mod h1:DFIJJjhMj0TSXPz+0ni4nyZ9gtTtC40Vh/TGRugtyWw=
 github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
 github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc=
@@ -290,6 +290,8 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
 github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/h2non/gock v1.0.9 h1:17gCehSo8ZOgEsFKpQgqHiR7VLyjxdAG3lkhVvO9QZU=
 github.com/h2non/gock v1.0.9/go.mod h1:CZMcB0Lg5IWnr9bF79pPMg9WeV6WumxQiUJ1UvdO1iE=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw=
+github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
 github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
 github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -303,6 +305,7 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv
 github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
 github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
+github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
 github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -323,6 +326,8 @@ github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
+github.com/jenkins-x/go-scm v1.11.4 h1:uYEFE4Ty9nmlo8paG4ysSxmO5ii6uj7nCQIsSh+ppXU=
+github.com/jenkins-x/go-scm v1.11.4/go.mod h1:8zDNVAps5UCZ7nDVBCzkIrPaSGN4vHq+1bDrHLk6JJc=
 github.com/jenkins-zh/jenkins-cli v0.0.32/go.mod h1:uE1mH9PNITrg0sugv6HXuM/CSddg0zxXoYu3w57I3JY=
 github.com/jenkins-zh/jenkins-client v0.0.9 h1:yqWtjLifYWbVxR+wFdExh/cHSQ54i/Cdco2MYkc/5vI=
 github.com/jenkins-zh/jenkins-client v0.0.9/go.mod h1:ICBk7OOoTafVP//f/VfKZ34c0ff8vJwVnOsF9btiMYU=
@@ -350,6 +355,7 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW
 github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
+github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -397,6 +403,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
 github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
+github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
 github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
@@ -405,6 +413,8 @@ github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0Qu
 github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
+github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
 github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -486,9 +496,14 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
 github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
+github.com/shurcooL/githubv4 v0.0.0-20190718010115-4ba037080260 h1:xKXiRdBUtMVp64NaxACcyX4kvfmHJ9KrLU+JvyB1mdM=
+github.com/shurcooL/githubv4 v0.0.0-20190718010115-4ba037080260/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo=
+github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f h1:tygelZueB1EtXkPI6mQ4o9DQ0+FKW41hTbunoXZCTqk=
+github.com/shurcooL/graphql v0.0.0-20181231061246-d48a9a75455f/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
+github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
 github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -643,6 +658,7 @@ golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
+golang.org/x/net v0.0.0-20191021144547-ec77196f6094/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
@@ -814,6 +830,9 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/h2non/gentleman.v1 v1.0.4/go.mod h1:JYuHVdFzS4MKOXe0o+chKJ4hCe6tqKKw9XH9YP6WFrg=
+gopkg.in/h2non/gock.v1 v1.0.16 h1:F11k+OafeuFENsjei5t2vMTSTs9L62AdyTe4E1cgdG8=
+gopkg.in/h2non/gock.v1 v1.0.16/go.mod h1:XVuDAssexPLwgxCLMvDTWNU5eqklsydR6I5phZ9oPB8=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno=
diff --git a/pkg/client/git/client.go b/pkg/client/git/client.go
index f405c53..e4e5387 100644
--- a/pkg/client/git/client.go
+++ b/pkg/client/git/client.go
@@ -20,10 +20,10 @@ import (
 	"context"
 	"errors"
 	"fmt"
-	goscm "github.com/drone/go-scm/scm"
-	"github.com/drone/go-scm/scm/driver/github"
-	"github.com/drone/go-scm/scm/driver/gitlab"
-	"github.com/drone/go-scm/scm/transport/oauth2"
+	goscm "github.com/jenkins-x/go-scm/scm"
+	"github.com/jenkins-x/go-scm/scm/driver/github"
+	"github.com/jenkins-x/go-scm/scm/driver/gitlab"
+	"github.com/jenkins-x/go-scm/scm/transport/oauth2"
 	v1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
 	"k8s.io/apimachinery/pkg/types"
@@ -58,19 +58,21 @@ func (c *ClientFactory) GetClient() (client *goscm.Client, err error) {
 		return
 	}
 
-	var gitToken string
-	if gitToken, err = c.getTokenFromSecret(c.secretRef); err != nil {
-		return
-	}
+	if c.secretRef != nil {
+		var gitToken string
+		if gitToken, err = c.getTokenFromSecret(c.secretRef); err != nil {
+			return
+		}
 
-	client.Client = &http.Client{
-		Transport: &oauth2.Transport{
-			Source: oauth2.StaticTokenSource(
-				&goscm.Token{
-					Token: gitToken,
-				},
-			),
-		},
+		client.Client = &http.Client{
+			Transport: &oauth2.Transport{
+				Source: oauth2.StaticTokenSource(
+					&goscm.Token{
+						Token: gitToken,
+					},
+				),
+			},
+		}
 	}
 	return
 }
diff --git a/pkg/kapis/common/options.go b/pkg/kapis/common/options.go
index f03efeb..0027411 100644
--- a/pkg/kapis/common/options.go
+++ b/pkg/kapis/common/options.go
@@ -19,6 +19,7 @@ import (
 	"github.com/emicklei/go-restful"
 	"kubesphere.io/devops/pkg/kapis"
 	"sigs.k8s.io/controller-runtime/pkg/client"
+	"strconv"
 )
 
 // Options contain options needed by creating handlers.
@@ -31,6 +32,11 @@ var (
 	DevopsPathParameter = restful.PathParameter("devops", "DevOps project name")
 	// NamespacePathParameter is a path parameter definition for namespace
 	NamespacePathParameter = restful.PathParameter("namespace", "The namespace name")
+
+	// PageNumberQueryParameter is a restful query parameter of the page number
+	PageNumberQueryParameter = restful.QueryParameter("pageNumber", "The number of paging").DataType("int")
+	// PageSizeQueryParameter is a restful query parameter of the page size
+	PageSizeQueryParameter = restful.QueryParameter("pageSize", "The size of each paging data").DataType("int")
 )
 
 // GetPathParameter returns the path parameter value from a request
@@ -43,6 +49,22 @@ func GetQueryParameter(req *restful.Request, param *restful.Parameter) string {
 	return req.QueryParameter(param.Data().Name)
 }
 
+// GetPageParameters returns the page number and page size from a request
+// the default value of page number is 1, page size is 10 if the number string is invalid
+func GetPageParameters(req *restful.Request) (pageNumber, pageSize int) {
+	pageNumberStr := req.QueryParameter(PageNumberQueryParameter.Data().Name)
+	pageSizeStr := req.QueryParameter(PageSizeQueryParameter.Data().Name)
+
+	var err error
+	if pageNumber, err = strconv.Atoi(pageNumberStr); err != nil {
+		pageNumber = 1
+	}
+	if pageSize, err = strconv.Atoi(pageSizeStr); err != nil {
+		pageSize = 10
+	}
+	return
+}
+
 // Response is a common response method
 func Response(req *restful.Request, res *restful.Response, object interface{}, err error) {
 	if err != nil {
diff --git a/pkg/kapis/devops/v1alpha3/scm/route.go b/pkg/kapis/devops/v1alpha3/scm/route.go
index cc8d25a..c290a74 100644
--- a/pkg/kapis/devops/v1alpha3/scm/route.go
+++ b/pkg/kapis/devops/v1alpha3/scm/route.go
@@ -33,6 +33,7 @@ var (
 	pathParameterGitRepository    = restful.PathParameter("gitrepository", "The GitRepository customs resource")
 	queryParameterSecret          = restful.QueryParameter("secret", "the secret name")
 	queryParameterSecretNamespace = restful.QueryParameter("secretNamespace", "the namespace of target secret")
+	queryParameterIncludeUser     = restful.QueryParameter("includeUser", "Indicate if you want to include the current user")
 )
 
 // RegisterRoutersForSCM registers the APIs which related to scm
@@ -56,6 +57,7 @@ func registerSCMAPIs(ws *restful.WebService, h *handler) {
 		Param(pathParameterSCM).
 		Param(queryParameterSecret).
 		Param(queryParameterSecretNamespace).
+		Param(queryParameterIncludeUser.DataType("boolean").DefaultValue("true")).
 		Doc("List all the readable organizations").
 		Returns(http.StatusOK, api.StatusOK, []organization{}))
 
@@ -63,10 +65,12 @@ func registerSCMAPIs(ws *restful.WebService, h *handler) {
 		To(h.listRepositories).
 		Param(pathParameterSCM).
 		Param(pathParameterOrganization).
-		Param(queryParameterSecret).
-		Param(queryParameterSecretNamespace).
-		Doc("List all the readable repositories").
-		Returns(http.StatusOK, api.StatusOK, []repository{}))
+		Param(queryParameterSecret.Required(true)).
+		Param(queryParameterSecretNamespace.Required(true)).
+		Param(common.PageNumberQueryParameter).
+		Param(common.PageSizeQueryParameter).
+		Doc("List all the readable Repositories").
+		Returns(http.StatusOK, api.StatusOK, repositoryListResult{}))
 }
 
 func registerGitRepositoryAPIs(ws *restful.WebService, h *handler) {
diff --git a/pkg/kapis/devops/v1alpha3/scm/scmhandler.go b/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
index a44739e..197d5cf 100644
--- a/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
+++ b/pkg/kapis/devops/v1alpha3/scm/scmhandler.go
@@ -18,11 +18,13 @@ package scm
 
 import (
 	"context"
-	goscm "github.com/drone/go-scm/scm"
+	"fmt"
 	"github.com/emicklei/go-restful"
+	goscm "github.com/jenkins-x/go-scm/scm"
 	v1 "k8s.io/api/core/v1"
 	"kubesphere.io/devops/pkg/client/git"
 	"kubesphere.io/devops/pkg/kapis"
+	"kubesphere.io/devops/pkg/kapis/common"
 	"sigs.k8s.io/controller-runtime/pkg/client"
 )
 
@@ -44,7 +46,7 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
 	secretName := request.QueryParameter("secret")
 	secretNamespace := request.QueryParameter("secretNamespace")
 
-	_, code, err := h.getOrganizations(scm, secretName, secretNamespace, 1)
+	_, code, err := h.getOrganizations(scm, secretName, secretNamespace, 1, 1, false)
 
 	response.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
 	verifyResult := git.VerifyResult(err, code)
@@ -52,49 +54,62 @@ func (h *handler) verify(request *restful.Request, response *restful.Response) {
 	_ = response.WriteAsJson(verifyResult)
 }
 
-func (h *handler) getOrganizations(scm, secret, namespace string, size int) (orgs []*goscm.Organization, code int, err error) {
+func (h *handler) getOrganizations(scm, secret, namespace string, page, size int, includeUser bool) (orgs []*goscm.Organization, code int, err error) {
 	factory := git.NewClientFactory(scm, &v1.SecretReference{
 		Namespace: namespace, Name: secret,
 	}, h.Client)
 
+	ctx := context.Background()
 	var c *goscm.Client
 	if c, err = factory.GetClient(); err == nil {
 		var resp *goscm.Response
 
-		if orgs, resp, err = c.Organizations.List(context.TODO(), goscm.ListOptions{Size: size, Page: 1}); err == nil {
+		if orgs, resp, err = c.Organizations.List(ctx, goscm.ListOptions{Size: size, Page: page}); err == nil {
 			code = resp.Status
 		} else {
 			code = 101
 		}
+
+		if includeUser {
+			var user string
+			if user, err = h.getCurrentUsername(c); err == nil {
+				orgs = append(orgs, &goscm.Organization{
+					Name:   user,
+					Avatar: fmt.Sprintf("https://avatars.githubusercontent.com/%s", user),
+				})
+			}
+		}
 	} else {
 		code = 100
 	}
 	return
 }
 
-func (h *handler) getRepositories(scm, org, secret, namespace string, size int) (repos []*goscm.Repository, code int, err error) {
+func (h *handler) getRepositories(scm, org, secret, namespace string, page, size int) (repos []*goscm.Repository, code int, err error) {
 	factory := git.NewClientFactory(scm, &v1.SecretReference{
 		Namespace: namespace, Name: secret,
 	}, h.Client)
 
 	var c *goscm.Client
 	if c, err = factory.GetClient(); err == nil {
-		var resp *goscm.Response
-
-		var allRepos []*goscm.Repository
-		if allRepos, resp, err = c.Repositories.List(context.TODO(), goscm.ListOptions{
-			Page: 1,
-			Size: size,
-		}); err == nil {
-			code = resp.Status
-
-			for i := range allRepos {
-				repo := allRepos[i]
-				if repo.Namespace == org {
-					repos = append(repos, repo)
-				}
+		// check if the org name is an user account name
+		var user string
+		var listRepositoryFunc listRepository
+		if user, err = h.getCurrentUsername(c); err == nil {
+			if user == org {
+				listRepositoryFunc = c.Repositories.ListUser
+			} else {
+				listRepositoryFunc = c.Repositories.ListOrganisation
 			}
 		} else {
+			return
+		}
+
+		ctx := context.Background()
+		if repos, _, err = listRepositoryFunc(ctx, org, goscm.ListOptions{
+			Page: page,
+			Size: size,
+		}); err != nil {
 			code = 101
 		}
 	} else {
@@ -103,12 +118,16 @@ func (h *handler) getRepositories(scm, org, secret, namespace string, size int)
 	return
 }
 
+type listRepository func(context.Context, string, goscm.ListOptions) ([]*goscm.Repository, *goscm.Response, error)
+
 func (h *handler) listOrganizations(req *restful.Request, rsp *restful.Response) {
 	scm := req.PathParameter("scm")
 	secretName := req.QueryParameter("secret")
 	secretNamespace := req.QueryParameter("secretNamespace")
+	includeUser := common.GetQueryParameter(req, queryParameterIncludeUser) == "true"
+	pageNumber, pageSize := common.GetPageParameters(req)
 
-	orgs, _, err := h.getOrganizations(scm, secretName, secretNamespace, 1000)
+	orgs, _, err := h.getOrganizations(scm, secretName, secretNamespace, pageNumber, pageSize, includeUser)
 	if err != nil {
 		kapis.HandleError(req, rsp, err)
 	} else {
@@ -121,8 +140,9 @@ func (h *handler) listRepositories(req *restful.Request, rsp *restful.Response)
 	organization := req.PathParameter("organization")
 	secretName := req.QueryParameter("secret")
 	secretNamespace := req.QueryParameter("secretNamespace")
+	pageNumber, pageSize := common.GetPageParameters(req)
 
-	repos, _, err := h.getRepositories(scm, organization, secretName, secretNamespace, 10000)
+	repos, _, err := h.getRepositories(scm, organization, secretName, secretNamespace, pageNumber, pageSize)
 	if err != nil {
 		kapis.HandleError(req, rsp, err)
 	} else {
@@ -130,6 +150,17 @@ func (h *handler) listRepositories(req *restful.Request, rsp *restful.Response)
 	}
 }
 
+func (h *handler) getCurrentUsername(c *goscm.Client) (username string, err error) {
+	var user *goscm.User
+	user, _, err = c.Users.Find(context.Background())
+	if err != nil {
+		return
+	}
+
+	username = user.Login
+	return
+}
+
 func transformOrganizations(orgs []*goscm.Organization) (result []organization) {
 	if orgs != nil {
 		result = make([]organization, len(orgs))
@@ -143,15 +174,17 @@ func transformOrganizations(orgs []*goscm.Organization) (result []organization)
 	return
 }
 
-func transformRepositories(repos []*goscm.Repository) (result []repository) {
-	if repos != nil {
-		result = make([]repository, len(repos))
-		for i := range repos {
-			result[i] = repository{
-				Name:          repos[i].Name,
-				DefaultBranch: repos[i].Branch,
+func transformRepositories(goSCMRepos []*goscm.Repository) (result *repositoryListResult) {
+	result = &repositoryListResult{}
+	if goSCMRepos != nil {
+		repos := make([]repository, len(goSCMRepos))
+		for i := range goSCMRepos {
+			repos[i] = repository{
+				Name:          goSCMRepos[i].Name,
+				DefaultBranch: goSCMRepos[i].Branch,
 			}
 		}
+		result.Repositories.Items = repos
 	}
 	return
 }
diff --git a/pkg/kapis/devops/v1alpha3/scm/types.go b/pkg/kapis/devops/v1alpha3/scm/types.go
index fb8649c..d041b22 100644
--- a/pkg/kapis/devops/v1alpha3/scm/types.go
+++ b/pkg/kapis/devops/v1alpha3/scm/types.go
@@ -28,3 +28,9 @@ type repository struct {
 	DefaultBranch string `json:"defaultBranch"`
 	Name          string `json:"name"`
 }
+
+type repositoryListResult struct {
+	Repositories struct {
+		Items []repository `json:"items"`
+	} `json:"repositories"`
+}


Test patch:
diff --git a/controllers/gitrepository/gitrepository_webhook_controller_test.go b/controllers/gitrepository/gitrepository_webhook_controller_test.go
index d00753e..207d004 100644
--- a/controllers/gitrepository/gitrepository_webhook_controller_test.go
+++ b/controllers/gitrepository/gitrepository_webhook_controller_test.go
@@ -19,10 +19,10 @@ package gitrepository
 import (
 	"context"
 	"fmt"
-	"github.com/drone/go-scm/scm"
-	"github.com/drone/go-scm/scm/driver/github"
 	"github.com/go-logr/logr"
 	testing2 "github.com/go-logr/logr/testing"
+	"github.com/jenkins-x/go-scm/scm"
+	"github.com/jenkins-x/go-scm/scm/driver/github"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/pkg/client/git/client_test.go b/pkg/client/git/client_test.go
index 1db4cf0..fc427ff 100644
--- a/pkg/client/git/client_test.go
+++ b/pkg/client/git/client_test.go
@@ -18,8 +18,8 @@ package git
 
 import (
 	"fmt"
-	"github.com/drone/go-scm/scm"
-	"github.com/drone/go-scm/scm/driver/github"
+	"github.com/jenkins-x/go-scm/scm"
+	"github.com/jenkins-x/go-scm/scm/driver/github"
 	"github.com/stretchr/testify/assert"
 	v1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
diff --git a/pkg/kapis/common/options_test.go b/pkg/kapis/common/options_test.go
new file mode 100644
index 0000000..233cbb1
--- /dev/null
+++ b/pkg/kapis/common/options_test.go
@@ -0,0 +1,66 @@
+// Copyright 2022 KubeSphere Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+package common
+
+import (
+	"github.com/emicklei/go-restful"
+	"net/http"
+	"testing"
+)
+
+func TestGetPageParameters(t *testing.T) {
+	type args struct {
+		req *restful.Request
+	}
+	tests := []struct {
+		name           string
+		args           args
+		wantPageNumber int
+		wantPageSize   int
+	}{{
+		name: "normal case, page number is 1, size is 20",
+		args: args{
+			req: getRestfulRequestFromURL("/api?pageNumber=1&pageSize=20"),
+		},
+		wantPageNumber: 1,
+		wantPageSize:   20,
+	}, {
+		name: "with invalid page number and size",
+		args: args{
+			req: getRestfulRequestFromURL("/api?pageNumber=a&pageSize=b"),
+		},
+		wantPageNumber: 1,
+		wantPageSize:   10,
+	}}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			gotPageNumber, gotPageSize := GetPageParameters(tt.args.req)
+			if gotPageNumber != tt.wantPageNumber {
+				t.Errorf("GetPageParameters() gotPageNumber = %v, want %v", gotPageNumber, tt.wantPageNumber)
+			}
+			if gotPageSize != tt.wantPageSize {
+				t.Errorf("GetPageParameters() gotPageSize = %v, want %v", gotPageSize, tt.wantPageSize)
+			}
+		})
+	}
+}
+
+func getRestfulRequestFromURL(requestURL string) *restful.Request {
+	defaultRequest, _ := http.NewRequest(http.MethodGet, requestURL, nil)
+	return &restful.Request{
+		Request: defaultRequest,
+	}
+}
diff --git a/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go b/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
index 38d3af8..0d78aa6 100644
--- a/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
+++ b/pkg/kapis/devops/v1alpha3/scm/scmhandler_test.go
@@ -116,7 +116,7 @@ func TestSCMAPI(t *testing.T) {
 		name: "get the organization list",
 		args: args{
 			method: http.MethodGet,
-			uri:    "/scms/github/organizations?secret=token&secretNamespace=default",
+			uri:    "/scms/github/organizations?secret=token&secretNamespace=default&includeUser=false",
 		},
 		prepare: func() {
 			var mockHeaders = map[string]string{
@@ -154,7 +154,110 @@ func TestSCMAPI(t *testing.T) {
 			assert.Equal(t, "github", orgs[0].Name)
 		},
 	}, {
-		name: "get the repository list",
+		name: "get the organization list include current user",
+		args: args{
+			method: http.MethodGet,
+			uri:    "/scms/github/organizations?secret=token&secretNamespace=default&includeUser=true",
+		},
+		prepare: func() {
+			var mockHeaders = map[string]string{
+				"X-GitHub-Request-Id":   "DD0E:6011:12F21A8:1926790:5A2064E2",
+				"X-RateLimit-Limit":     "60",
+				"X-RateLimit-Remaining": "59",
+				"X-RateLimit-Reset":     "1512076018",
+			}
+
+			var mockPageHeaders = map[string]string{
+				"Link": `<https://api.github.com/resource?page=1>; rel="next",` +
+					`<https://api.github.com/resource?page=1>; rel="prev",` +
+					`<https://api.github.com/resource?page=1>; rel="first",` +
+					`<https://api.github.com/resource?page=1>; rel="last"`,
+			}
+
+			gock.New("https://api.github.com").
+				Get("/user/orgs").
+				MatchParam("per_page", "1").
+				MatchParam("page", "1").
+				Reply(200).
+				Type("application/json").
+				SetHeaders(mockHeaders).
+				SetHeaders(mockPageHeaders).
+				File("testdata/orgs.json")
+
+			gock.New("https://api.github.com").
+				Get("/user").
+				Reply(200).
+				Type("application/json").
+				SetHeader("X-GitHub-Request-Id", "DD0E:6011:12F21A8:1926790:5A2064E2").
+				SetHeader("X-RateLimit-Limit", "60").
+				SetHeader("X-RateLimit-Remaining", "59").
+				SetHeader("X-RateLimit-Reset", "1512076018").
+				File("testdata/user.json")
+		},
+		verify: func(code int, response []byte, t *testing.T) {
+			assert.Equal(t, 200, code)
+
+			var orgs []organization
+			err := json.Unmarshal(response, &orgs)
+			assert.Nil(t, err)
+			assert.Equal(t, 2, len(orgs))
+			assert.Equal(t, "https://github.com/images/error/octocat_happy.gif", orgs[0].Avatar)
+			assert.Equal(t, "github", orgs[0].Name)
+			assert.Equal(t, "octocat", orgs[1].Name)
+		},
+	}, {
+		name: "get the repository list with the organization name",
+		args: args{
+			method: http.MethodGet,
+			uri:    "/scms/github/organizations/octocat-org/repositories?secret=token&secretNamespace=default",
+		},
+		prepare: func() {
+			var mockHeaders = map[string]string{
+				"X-GitHub-Request-Id":   "DD0E:6011:12F21A8:1926790:5A2064E2",
+				"X-RateLimit-Limit":     "60",
+				"X-RateLimit-Remaining": "59",
+				"X-RateLimit-Reset":     "1512076018",
+			}
+
+			var mockPageHeaders = map[string]string{
+				"Link": `<https://api.github.com/resource?page=1>; rel="next",` +
+					`<https://api.github.com/resource?page=1>; rel="prev",` +
+					`<https://api.github.com/resource?page=1>; rel="first",` +
+					`<https://api.github.com/resource?page=1>; rel="last"`,
+			}
+
+			gock.New("https://api.github.com").
+				Get("orgs/octocat-org/repos").
+				MatchParam("per_page", "10").
+				MatchParam("page", "1").
+				Reply(200).
+				Type("application/json").
+				SetHeaders(mockHeaders).
+				SetHeaders(mockPageHeaders).
+				File("testdata/repos.json")
+
+			gock.New("https://api.github.com").
+				Get("/user").
+				Reply(200).
+				Type("application/json").
+				SetHeader("X-GitHub-Request-Id", "DD0E:6011:12F21A8:1926790:5A2064E2").
+				SetHeader("X-RateLimit-Limit", "60").
+				SetHeader("X-RateLimit-Remaining", "59").
+				SetHeader("X-RateLimit-Reset", "1512076018").
+				File("testdata/user.json")
+		},
+		verify: func(code int, response []byte, t *testing.T) {
+			assert.Equal(t, 200, code)
+
+			var repos repositoryListResult
+			err := json.Unmarshal(response, &repos)
+			assert.Nil(t, err)
+			assert.Equal(t, 2, len(repos.Repositories.Items))
+			assert.Equal(t, "Hello-World", repos.Repositories.Items[0].Name)
+			assert.Equal(t, "master", repos.Repositories.Items[0].DefaultBranch)
+		},
+	}, {
+		name: "get the repository list with the individual name",
 		args: args{
 			method: http.MethodGet,
 			uri:    "/scms/github/organizations/octocat/repositories?secret=token&secretNamespace=default",
@@ -175,7 +278,7 @@ func TestSCMAPI(t *testing.T) {
 			}
 
 			gock.New("https://api.github.com").
-				Get("user/repos").
+				Get("users/octocat/repos").
 				MatchParam("per_page", "1").
 				MatchParam("page", "1").
 				Reply(200).
@@ -183,16 +286,26 @@ func TestSCMAPI(t *testing.T) {
 				SetHeaders(mockHeaders).
 				SetHeaders(mockPageHeaders).
 				File("testdata/repos.json")
+
+			gock.New("https://api.github.com").
+				Get("/user").
+				Reply(200).
+				Type("application/json").
+				SetHeader("X-GitHub-Request-Id", "DD0E:6011:12F21A8:1926790:5A2064E2").
+				SetHeader("X-RateLimit-Limit", "60").
+				SetHeader("X-RateLimit-Remaining", "59").
+				SetHeader("X-RateLimit-Reset", "1512076018").
+				File("testdata/user.json")
 		},
 		verify: func(code int, response []byte, t *testing.T) {
 			assert.Equal(t, 200, code)
 
-			var repos []repository
+			var repos repositoryListResult
 			err := json.Unmarshal(response, &repos)
 			assert.Nil(t, err)
-			assert.Equal(t, 1, len(repos))
-			assert.Equal(t, "Hello-World", repos[0].Name)
-			assert.Equal(t, "master", repos[0].DefaultBranch)
+			assert.Equal(t, 2, len(repos.Repositories.Items))
+			assert.Equal(t, "Hello-World", repos.Repositories.Items[0].Name)
+			assert.Equal(t, "master", repos.Repositories.Items[0].DefaultBranch)
 		},
 	}}
 	for _, tt := range tests {
diff --git a/pkg/kapis/devops/v1alpha3/scm/testdata/user.json b/pkg/kapis/devops/v1alpha3/scm/testdata/user.json
new file mode 100644
index 0000000..b28e7ba
--- /dev/null
+++ b/pkg/kapis/devops/v1alpha3/scm/testdata/user.json
@@ -0,0 +1,32 @@
+{
+  "login": "octocat",
+  "id": 1,
+  "avatar_url": "https://github.com/images/error/octocat_happy.gif",
+  "gravatar_id": "",
+  "url": "https://api.github.com/users/octocat",
+  "html_url": "https://github.com/octocat",
+  "followers_url": "https://api.github.com/users/octocat/followers",
+  "following_url": "https://api.github.com/users/octocat/following{/other_user}",
+  "gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
+  "starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
+  "subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
+  "organizations_url": "https://api.github.com/users/octocat/orgs",
+  "repos_url": "https://api.github.com/users/octocat/repos",
+  "events_url": "https://api.github.com/users/octocat/events{/privacy}",
+  "received_events_url": "https://api.github.com/users/octocat/received_events",
+  "type": "User",
+  "site_admin": false,
+  "name": "monalisa octocat",
+  "company": "GitHub",
+  "blog": "https://github.com/blog",
+  "location": "San Francisco",
+  "email": "octocat@github.com",
+  "hireable": false,
+  "bio": "There once was...",
+  "public_repos": 2,
+  "public_gists": 1,
+  "followers": 20,
+  "following": 0,
+  "created_at": "2008-01-14T04:33:35Z",
+  "updated_at": "2008-01-14T04:33:35Z"
+}
\ No newline at end of file