有没有办法在通过 HTTPS 为 Google 源存储库调用 git 克隆时传递访问令牌

Is there a way to pass access tokens when calling git clone over HTTPS for Google Source Repository

我一直在尝试使用 Google Cloud Functions (python 3.7) 来基本上克隆 Google 源存储库。我正在使用 GitPython 库,并且 Cloud Functions 的服务帐户对我要克隆的存储库具有 源存储库 Reader 访问权限。

最初,我尝试将 gcloud.sh credential.helper 传递给 git 配置,但似乎 Cloud SDK 未安装在 Cloud Functions 环境中(至少在 Python 3.7 环境中)。这是我的代码的要点:

from git import Repo
import tempfile

def git_clone():
    
    local_repo = tempfile.gettempdir()+'/localrepo'
    repo = Repo.init(local_repo)
    origin = repo.create_remote('origin', 'https://source.developers.google.com/p/PROJECT/r/REPO')

    repo.config_writer().set_value("user", "name", "gsr-to-gcs-backup-function").release()
    repo.config_writer().set_value("user", "email", "gsr-to-gcs-backup-function@PROJECT.iam.gserviceaccount.com").release()
    repo.config_writer().set_value("credential \"https://source.developers.google.com\"", "helper", "gcloud.sh").release()

    assert origin.exists()
    assert origin == repo.remotes.origin == repo.remotes['origin']
    
    origin.fetch()

如果 运行 在 Cloud Functions 上,该函数将抛出以下错误,因为默认情况下,如果没有凭证助手,https 方法将请求 用户名密码

git.exc.GitCommandError: Cmd('git') failed due to: exit code(128) cmdline: git fetch -v origin stderr: 'fatal: could not read Username for 'https://source.developers.google.com': Input/output error'

我只能找到下面的答案来传递令牌以及 git clone 命令,但它没有回答如何传递令牌:

如果我从云 shell 启动该命令,它将被挂起:

gcloud auth git-helper store --account=YOUR_ACCOUNT --ignore-unknown $@

这是我计划使用上述代码实现的类似内容(不是正确的代码):

Repo.clone_from("https://source.developers.google.com/p/PROJECT/r/REPO",tempfile.gettempdir(), multi_options=['--config credential.helper={}'.format(MYTOKEN)], branch='master')

我不想将 SSH 密钥作为克隆方法,因为我想稍后将其部署到生产环境中,轮换密钥会很麻烦。

询问的用户名只是服务帐户地址和凭据,可以是临时生成的 OAuth 2.0 访问令牌。所以,我最终做的是:

from git import Repo
import tempfile
import urllib.parse
import google.auth
import google.auth.transport.requests

def get_token():
    creds, project = google.auth.default()
    # creds.valid is False, and creds.token is None
    # # Need to refresh credentials to populate those
    auth_req = google.auth.transport.requests.Request()
    creds.refresh(auth_req)
    # Now you can use creds.token
    return creds.token

def url_parse():
    query = 'gsr-to-gcs-backup-function@PROJECT.iam.gserviceaccount.com'
    return urllib.parse.quote(query)

def git_clone():
    encoded_url = url_parse()
    credentials = get_token()
    
    local_repo = tempfile.gettempdir()+'/localrepo' 
    Repo.clone_from(f"https://{encoded_url}:{credentials}@source.developers.google.com/p/PROJECT/r/REPO",local_repo, branch='master')

def main(*args):
    git_clone()

注意:这只是我的代码的一部分。我想要的是将其复制到 GCS 存储桶中。但这超出了这个问题的范围。