Skip to content

Fix GH_REPO usage with secret commands - #10535

Closed
williammartin wants to merge 5 commits into
trunkfrom
10525-gh-secret-subcommands-dont-work-anymore-if-called-outside-of-git-repository
Closed

Fix GH_REPO usage with secret commands#10535
williammartin wants to merge 5 commits into
trunkfrom
10525-gh-secret-subcommands-dont-work-anymore-if-called-outside-of-git-repository

Conversation

@williammartin

@williammartin williammartin commented Mar 4, 2025

Copy link
Copy Markdown
Member

Description

Fixes #10525

Draft because I'm not convinced about the cost of the commented "spooky action at a distance" but wanted to put something out there.

I removed OverrideBaseRepoFunc because it was in my opinion, not a very good abstraction to have exported as seen in the call site of gh api:

cmdutil.OverrideBaseRepoFunc(f, "")

Now replaced by:

cmdutil.PrioritiseEnvBaseRepoFunc(f.BaseRepo)

The code was then inlined into EnableRepoOverride.

Acceptance

Given my cwd is not a git repo
And I have GH_REPO set to a repo I have permissions on
When I run any of the gh secret commands
Then I am able to interact with secrets on that repo

Before:

➜  workspace GH_REPO=williammartin-test-org/test-repo gh secret list
failed to run git: fatal: not a git repository (or any of the parent directories): .git

After:

➜  workspace GH_REPO=williammartin-test-org/test-repo ~/workspace/cli/bin/gh secret list | cat
FOO     2025-01-09T16:39:07Z

@williammartin
williammartin force-pushed the 10525-gh-secret-subcommands-dont-work-anymore-if-called-outside-of-git-repository branch from 9ade48d to 024bb68 Compare March 4, 2025 14:03

@andyfeller andyfeller left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think this is as clean of a solution we're likely to get outside of refactoring gh to use spf13/viper which is non-trivial and not being advocated for at this point.

Comment thread pkg/cmdutil/repo_override.go Outdated
Comment on lines +61 to +71
repoOverride, ok := os.LookupEnv("GH_REPO")
// If the envrionment variable was set, then set the value of the `repo` flag,
// this ensures that checks for `HasChanged` work correctly. It's a bit "spooky"
// action at a distance because the flag will not have been set by the user,
// but perhaps it makes sense?
//
// The reason we need this is because there are `secret` commands that need to know whether
// the user set the repo, and the alternative is them having knowledge of the flag and env var,
// or by adjusting all our types so that the "source" of the BaseRepo is surfaced, which is a
// pretty big change.
if ok {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Nothing wrong with the logic; just stating how this works.

If a user has GH_REPO="", then we will attempt to set the flag with the value if empty and defer to spf13/pflag to determine if the flag has been changed or not.

Comment thread pkg/cmdutil/repo_override.go
Comment thread pkg/cmdutil/repo_override.go Outdated
Comment thread pkg/cmdutil/repo_override.go Outdated
Comment on lines +55 to +61
// First, get the value of the flag.
// We can ignore errors here because the flag is guaranteed to exist and be string.
userProvidedRepo, _ := cmd.Flags().GetString("repo")
if userProvidedRepo == "" {
// If there was no flag set, then check the GH_REPO environment variable,
// which has lower precedence.
repoOverride, ok := os.LookupEnv("GH_REPO")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just going to say this is more elegant of a solution than I was considering when we initially discussed this. I hadn't considered the utility logic setting up the persistent flag.

This helps keep the concerns in 1 place, so hopefully easier to grok and manage.

Comment on lines +89 to 99
type baseRepoFn func() (ghrepo.Interface, error)

func PrioritiseEnvBaseRepoFunc(baseRepo baseRepoFn) func() (ghrepo.Interface, error) {
return func() (ghrepo.Interface, error) {
repo := os.Getenv("GH_REPO")
if repo == "" {
return baseRepo()
}
return ghrepo.FromFullName(repo)
}
return f.BaseRepo
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

From what I can gather, there aren't any functional changes to this logic but refining it:

  • decouple this from Factory for some arbitrary logic that provides a ghrepo.Interface like the base repo functions
  • focuses this solely on the environmental override
  • defers to the provided default if environment is a no go

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

focuses this solely on the environmental override

That's the functional change. Previously it also accepted a string to be like "just return this", which frankly, is a bad solution because the caller should just choose not to call the function if it were empty.

@williammartin
williammartin force-pushed the 10525-gh-secret-subcommands-dont-work-anymore-if-called-outside-of-git-repository branch from 8e02b7b to fa4e15c Compare March 4, 2025 14:53
@andyfeller

Copy link
Copy Markdown
Contributor

@williammartin : With #10539 reviewed and merged, what are your thoughts regarding this draft?

Is there a larger issue to follow up on with the former being a short term patch?

@williammartin

Copy link
Copy Markdown
Member Author

Unlikely we are going to prioritise this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

gh secret subcommands don't work anymore if called outside of Git repository

3 participants