Skip to content

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

Description

@AnimMouse

Describe the bug

After upgrading to GitHub CLI 2.67.0 all gh secret set commands that are run outside of git repository fails with this message:

failed to run git: fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Actions like this are now failing if they are run without using actions/checkout.

Related: #4688 #10209

Maybe related: #10352

Affected version

2.67.0 2.66.1 2.66.0

Steps to reproduce the behavior

  1. Upgrade to GitHub CLI 2.67.0
  2. Run GH_REPO=AnimMouse/test-repo gh secret set test_secret
  3. See error:
failed to run git: fatal: not a git repository (or any parent up to mount point /)
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).

Expected vs actual behavior

Earlier version of gh secret worked without checking out the repository.

GH_REPO=AnimMouse/test-repo gh secret set test_secret
? Paste your secret: 

Activity

  1. iamazeem commented on Mar 2, 2025

    @iamazeem
    Contributor

    Verified. 👍

    GH_REPO is working fine up to v2.65.0 for gh secret.

    The --repo flag is working fine.
    It may be used as an alternative (or a workaround):

    gh secret set test_secret --repo AnimMouse/test-repo gh

    And, in https://github.com/AnimMouse/setup-rclone/blob/main/update-config/action.yaml:

        - name: Update Rclone config for Unix-like
          if: runner.os == 'Linux' || runner.os == 'macOS'
          shell: bash
    -     run: base64 < ~/.config/rclone/rclone.conf | gh secret set "$rclone_config_secret_name"
    +     run: base64 < ~/.config/rclone/rclone.conf | gh secret set "$rclone_config_secret_name" --repo '${{ github.repository }}'
          env:
            rclone_config_secret_name: ${{ inputs.rclone_config_secret_name }}
            GITHUB_TOKEN: ${{ inputs.token }}
    -       GH_REPO: ${{ github.repository }}

    Other commands such as gh variable list, gh pr list, gh issue list, and gh release list are working fine with GH_REPO in a non-git directory.
    The only affected command seems to be gh secret.

  2. iamazeem commented on Mar 2, 2025

    @iamazeem
    Contributor

    Related to #10209:

    // If the user specified a repo directly, then we're using the OverrideBaseRepoFunc set by EnableRepoOverride
    // So there's no reason to use the specialised BaseRepoFunc that requires remote disambiguation.
    opts.BaseRepo = f.BaseRepo
    if !cmd.Flags().Changed("repo") {
    // If they haven't specified a repo directly, then we will wrap the BaseRepoFunc in one that errors if
    // there might be multiple valid remotes.
    opts.BaseRepo = shared.RequireNoAmbiguityBaseRepoFunc(opts.BaseRepo, f.Remotes)
    // But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
    // resolve the ambiguity.
    if opts.IO.CanPrompt() {
    opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
    }

    // If the user specified a repo directly, then we're using the OverrideBaseRepoFunc set by EnableRepoOverride
    // So there's no reason to use the specialised BaseRepoFunc that requires remote disambiguation.
    opts.BaseRepo = f.BaseRepo
    if !cmd.Flags().Changed("repo") {
    // If they haven't specified a repo directly, then we will wrap the BaseRepoFunc in one that errors if
    // there might be multiple valid remotes.
    opts.BaseRepo = shared.RequireNoAmbiguityBaseRepoFunc(opts.BaseRepo, f.Remotes)
    // But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
    // resolve the ambiguity.
    if opts.IO.CanPrompt() {
    opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
    }
    }

    // If the user specified a repo directly, then we're using the OverrideBaseRepoFunc set by EnableRepoOverride
    // So there's no reason to use the specialised BaseRepoFunc that requires remote disambiguation.
    opts.BaseRepo = f.BaseRepo
    if !cmd.Flags().Changed("repo") {
    // If they haven't specified a repo directly, then we will wrap the BaseRepoFunc in one that errors if
    // there might be multiple valid remotes.
    opts.BaseRepo = shared.RequireNoAmbiguityBaseRepoFunc(opts.BaseRepo, f.Remotes)
    // But if we are able to prompt, then we will wrap that up in a BaseRepoFunc that can prompt the user to
    // resolve the ambiguity.
    if opts.IO.CanPrompt() {
    opts.BaseRepo = shared.PromptWhenAmbiguousBaseRepoFunc(opts.BaseRepo, f.IOStreams, f.Prompter)
    }
    }

    Checking for GH_REPO in addition to --repo flag works fine (need to import os package):

    -			opts.BaseRepo = f.BaseRepo
    -			if !cmd.Flags().Changed("repo") {
    +			if cmd.Flags().Changed("repo") || os.Getenv("GH_REPO") != "" {
    +				opts.BaseRepo = f.BaseRepo
    +			} else {

    Here's the branch with this fix: https://github.com/iamazeem/cli/tree/10525-gh-secret-gh-repo-env-var

    Local test runs:

    # ./gh is a symlink here
    
    $ ./gh --version 
    gh version 2.66.1-227-g817eeb26 (2025-03-02)
    https://github.com/cli/cli/releases/latest
    
    $ ./gh secret list
    failed to run git: fatal: not a git repository (or any of the parent directories): .git
    
    $ GH_REPO=iamazeem/test ./gh secret set S1 --body "123"
    ✓ Set Actions secret S1 for iamazeem/test
    
    $ GH_REPO=iamazeem/test ./gh secret delete S1
    ✓ Deleted Actions secret S1 from iamazeem/test
  3. added
    priority-3Affects a small number of users or is largely cosmetic
    gh-secretrelating to the gh secret command
    on Mar 3, 2025
  4. williammartin commented on Mar 3, 2025

    @williammartin
    Member

    🤮 Sorry for the regression @AnimMouse

    I introduced this in #10209. This behaviour is shared across all secret commands.

    The fundamental issue here is that the logic we use to inject the --repo flag to various commands is also aware of GH_REPO but the check cmd.Flags().Changed("repo") is not.

    @iamazeem's (thanks) implementation is functionally correct, but I'd really like it if there were an approach that was little less coupled. I'll think about it, but we're going to release today or tomorrow so if I don't have a solution before then, I'll accept the current approach to ensure this is fixed asap.

  5. andyfeller commented on Mar 3, 2025

    @andyfeller
    Contributor

    Where is cli code already coupled with GH_REPO?

    "... but I'd really like it if there were an approach that was little less coupled."

    Agree with @williammartin. For perspective, here are the other places in GitHub CLI code that looks at GH_REPO environment variable.

    I feel like we should be able to do something for cmd-level logic to make this cleaner. 🤔

    Source: org:cli "GH_REPO" -path:**/*_test.go language:Go

    if cmd.Flags().Changed("repo") || os.Getenv("GH_REPO") != "" {
    opts.GitClient = &remoteGitClient{opts.BaseRepo, opts.HttpClient}
    opts.HasRepoOverride = true
    }

    opts.RepoOverride, _ = cmd.Flags().GetString("repo")
    // Workaround: Due to the way this command is implemented, we need to manually check GH_REPO.
    // Commands should use the standard BaseRepoOverride functionality to handle this behavior instead.
    if opts.RepoOverride == "" {
    opts.RepoOverride = os.Getenv("GH_REPO")
    }

    func OverrideBaseRepoFunc(f *Factory, override string) func() (ghrepo.Interface, error) {
    if override == "" {
    override = os.Getenv("GH_REPO")
    }
    if override != "" {
    return func() (ghrepo.Interface, error) {
    return ghrepo.FromFullName(override)
    }
    }
    return f.BaseRepo
    }

    cli/pkg/cmd/api/api.go

    Lines 563 to 574 in 817eeb2

    case "branch":
    if os.Getenv("GH_REPO") != "" {
    err = errors.New("unable to determine an appropriate value for the 'branch' placeholder")
    return m
    }
    if branch, e := opts.Branch(); e == nil {
    return branch
    } else {
    err = e
    }
    }

    https://github.com/cli/go-gh/blob/13104ed7b2db4b8c1a83de4248ddfaaab7682916/pkg/repository/repository.go#L117-L125

  6. williammartin commented on Mar 4, 2025

    @williammartin
    Member

    Acceptance Criteria

    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

  7. added
    coreThis issue is not accepting PRs from outside contributors
    and removed on Mar 4, 2025
  8. linked a pull request that will close this issueFix GH_REPO usage with secret commands #10535on Mar 4, 2025
  9. AnimMouse commented on Mar 6, 2025

    @AnimMouse
    Author

    Thank you @iamazeem, @williammartin, and @andyfeller for the speedy bug fix!

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingcoreThis issue is not accepting PRs from outside contributorsgh-secretrelating to the gh secret commandpriority-3Affects a small number of users or is largely cosmetic

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions