MCPcopy Index your code
hub / github.com/cli/cli / checkUpstreamProvenance

Function checkUpstreamProvenance

pkg/cmd/skills/install/install.go:1289–1362  ·  view source on GitHub ↗

checkUpstreamProvenance fetches the skill's SKILL.md via the contents API to check if it contains github-repo metadata pointing to a different repository, indicating the skill was re-published from an upstream source. In interactive mode, the user is asked whether to install from the re-publisher or

(opts *InstallOptions, client *api.Client, hostname string, skill discovery.Skill, commitSHA string)

Source from the content-addressed store, hash-verified

1287// installs from the re-publisher.
1288// Returns (repo to redirect to, whether upstream was detected, error).
1289func checkUpstreamProvenance(opts *InstallOptions, client *api.Client, hostname string, skill discovery.Skill, commitSHA string) (ghrepo.Interface, bool, error) {
1290 apiPath := fmt.Sprintf("repos/%s/%s/contents/%s?ref=%s",
1291 opts.repo.RepoOwner(), opts.repo.RepoName(),
1292 skill.Path+"/SKILL.md", commitSHA)
1293 var fileResp struct {
1294 Content string `json:"content"`
1295 Encoding string `json:"encoding"`
1296 }
1297 if err := client.REST(hostname, "GET", apiPath, nil, &fileResp); err != nil {
1298 return nil, false, nil //nolint:nilerr // best-effort check; failing to fetch is not fatal
1299 }
1300 if fileResp.Encoding != "base64" {
1301 return nil, false, nil
1302 }
1303 decoded, decodeErr := io.ReadAll(base64.NewDecoder(base64.StdEncoding, strings.NewReader(fileResp.Content)))
1304 if decodeErr != nil {
1305 return nil, false, nil //nolint:nilerr // best-effort; decode failure is not fatal
1306 }
1307 content := string(decoded)
1308
1309 result, parseErr := frontmatter.Parse(content)
1310 if parseErr != nil || result.Metadata.Meta == nil {
1311 //nolint:nilerr // unparseable frontmatter means no upstream to detect
1312 return nil, false, nil
1313 }
1314
1315 existingRepo, _ := result.Metadata.Meta["github-repo"].(string)
1316 if existingRepo == "" {
1317 return nil, false, nil
1318 }
1319
1320 currentRepoURL := source.BuildRepoURL(hostname, opts.repo.RepoOwner(), opts.repo.RepoName())
1321 if existingRepo == currentRepoURL {
1322 return nil, false, nil
1323 }
1324
1325 upstreamRepo, parseErr := source.ParseRepoURL(existingRepo)
1326 if parseErr != nil {
1327 //nolint:nilerr // invalid repo URL means we can't redirect; install normally
1328 return nil, false, nil
1329 }
1330
1331 cs := opts.IO.ColorScheme()
1332 upstreamLabel := ghrepo.FullName(upstreamRepo)
1333 repoSource := ghrepo.FullName(opts.repo)
1334
1335 fmt.Fprintf(opts.IO.ErrOut, "%s This skill was originally published in %s\n", cs.WarningIcon(), upstreamLabel)
1336
1337 if opts.Upstream {
1338 fmt.Fprintf(opts.IO.ErrOut, "Redirecting install to %s...\n", upstreamLabel)
1339 return upstreamRepo, true, nil
1340 }
1341
1342 if !opts.IO.CanPrompt() {
1343 fmt.Fprintf(opts.IO.ErrOut, " Installing from %s (use --upstream or interactive mode to choose upstream)\n", repoSource)
1344 return nil, true, nil
1345 }
1346

Callers 1

installRunFunction · 0.85

Calls 11

ParseFunction · 0.92
BuildRepoURLFunction · 0.92
ParseRepoURLFunction · 0.92
FullNameFunction · 0.92
ColorSchemeMethod · 0.80
WarningIconMethod · 0.80
CanPromptMethod · 0.80
RepoOwnerMethod · 0.65
RepoNameMethod · 0.65
RESTMethod · 0.65
SelectMethod · 0.65

Tested by

no test coverage detected