MCPcopy
hub / github.com/cli/cli / checkUpstreamProvenance

Function checkUpstreamProvenance

pkg/cmd/skills/install/install.go:1299–1372  ·  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

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

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