This is an automated email from the ASF dual-hosted git repository.
klesh pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-devlake.git
The following commit(s) were added to refs/heads/main by this push:
new 3a1cf9c8f fix: auto-enrich missing URL fields in GitHub scopes (#8661)
3a1cf9c8f is described below
commit 3a1cf9c8f8f665998ab761e5c884743df7df4442
Author: LE COZ Cedric <[email protected]>
AuthorDate: Thu Feb 26 15:22:59 2026 +0000
fix: auto-enrich missing URL fields in GitHub scopes (#8661)
Add automatic URL enrichment to PutScopes function to fetch missing
htmlUrl and cloneUrl fields from GitHub API when only fullName is provided.
This ensures gitextractor has the required URLs for cloning repositories.
- Fetch repo details from GitHub API when URLs are missing
- Populate htmlUrl and cloneUrl from API response
- Add graceful error handling for inaccessible repos
---
backend/plugins/github/api/scope_api.go | 47 +++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/backend/plugins/github/api/scope_api.go
b/backend/plugins/github/api/scope_api.go
index 6b8e951de..1ec037977 100644
--- a/backend/plugins/github/api/scope_api.go
+++ b/backend/plugins/github/api/scope_api.go
@@ -18,10 +18,13 @@ limitations under the License.
package api
import (
+ "context"
+
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/github/models"
+ "github.com/apache/incubator-devlake/plugins/github/tasks"
)
type PutScopesReqBody api.PutScopesReqBody[models.GithubRepo]
@@ -39,6 +42,50 @@ type ScopeDetail api.ScopeDetail[models.GithubRepo,
models.GithubScopeConfig]
// @Failure 500 {object} shared.ApiBody "Internal Error"
// @Router /plugins/github/connections/{connectionId}/scopes [PUT]
func PutScopes(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput,
errors.Error) {
+ // Enrich missing URL fields by fetching from GitHub API
+ connection, err := dsHelper.ConnApi.GetMergedConnection(input)
+ if err != nil {
+ return nil, err
+ }
+
+ apiClient, err := api.NewApiClientFromConnection(context.TODO(),
basicRes, connection)
+ if err != nil {
+ return nil, err
+ }
+
+ data, ok := input.Body["data"].([]interface{})
+ if ok {
+ for _, row := range data {
+ dict, ok := row.(map[string]interface{})
+ if !ok {
+ continue
+ }
+
+ // Check if URL fields are missing
+ htmlUrl, hasHtmlUrl := dict["htmlUrl"].(string)
+ cloneUrl, hasCloneUrl := dict["cloneUrl"].(string)
+ fullName, hasFullName := dict["fullName"].(string)
+
+ // If URLs are missing but we have fullName, fetch from
GitHub API
+ if hasFullName && fullName != "" && ((!hasHtmlUrl ||
htmlUrl == "") || (!hasCloneUrl || cloneUrl == "")) {
+ repo, err :=
getApiRepo(&tasks.GithubOptions{Name: fullName}, apiClient)
+ if err != nil {
+ // Log warning but don't fail - might
be a deleted/private repo
+ basicRes.GetLogger().Warn(err, "failed
to fetch repo details for %s, URL fields may be incomplete", fullName)
+ continue
+ }
+
+ // Populate missing fields from API
+ if !hasHtmlUrl || htmlUrl == "" {
+ dict["htmlUrl"] = repo.HTMLUrl
+ }
+ if !hasCloneUrl || cloneUrl == "" {
+ dict["cloneUrl"] = repo.CloneUrl
+ }
+ }
+ }
+ }
+
return dsHelper.ScopeApi.PutMultiple(input)
}