From 34f68b3c18f5b06ec84228fa8337c1c72513f3c4 Mon Sep 17 00:00:00 2001 From: Zettat123 Date: Tue, 14 Oct 2025 02:37:09 +0000 Subject: [PATCH] Support cloning actions and workflows from private repos (#123) Related to https://github.com/go-gitea/gitea/pull/32562 Resolve https://gitea.com/gitea/act_runner/issues/102 To support using actions and workflows from private repositories, we need to enable act_runner to clone private repositories. ~~But it is not easy to know if a repository is private and whether a token is required when cloning. In this PR, I added a new option `RetryToken`. By default, token is empty. When cloning a repo returns an `authentication required` error, `act_runner` will try to clone the repo again using `RetryToken` as the token.~~ In this PR, I added a new `getGitCloneToken` function. This function returns `GITEA_TOKEN` for cloning remote actions or remote reusable workflows when the cloneURL is from the same Gitea instance that the runner is registered to. Otherwise, it returns an empty string as token for cloning public repos from other instances (such as GitHub). Thanks @ChristopherHX for https://gitea.com/gitea/act/pulls/123#issuecomment-1046171 and https://gitea.com/gitea/act/pulls/123#issuecomment-1046285. Reviewed-on: https://gitea.com/gitea/act/pulls/123 Reviewed-by: ChristopherHX Reviewed-by: Lunny Xiao Co-authored-by: Zettat123 Co-committed-by: Zettat123 --- pkg/runner/reusable_workflow.go | 26 ++++++++++++++++++++++++-- pkg/runner/step_action_remote.go | 15 +++++---------- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/pkg/runner/reusable_workflow.go b/pkg/runner/reusable_workflow.go index f43ba241..a7385663 100644 --- a/pkg/runner/reusable_workflow.go +++ b/pkg/runner/reusable_workflow.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io/fs" + "net/url" "os" "path" "regexp" @@ -77,8 +78,7 @@ func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor { return newActionCacheReusableWorkflowExecutor(rc, filename, remoteReusableWorkflow) } - // FIXME: if the reusable workflow is from a private repository, we need to provide a token to access the repository. - token := "" + token := getGitCloneToken(rc.Config, remoteReusableWorkflow.CloneURL()) return common.NewPipelineExecutor( newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir, token)), @@ -319,3 +319,25 @@ func setReusedWorkflowCallerResult(rc *RunContext, runner Runner) common.Executo return nil } } + +// For Gitea +// getGitCloneToken returns GITEA_TOKEN when checkCloneURL returns true, +// otherwise returns an empty string +func getGitCloneToken(conf *Config, cloneURL string) string { + if !checkCloneURL(conf.GitHubInstance, cloneURL) { + return "" + } + return conf.GetToken() +} + +// For Gitea +// checkCloneURL returns true when the cloneURL is from the same Gitea instance that the runner is registered to +func checkCloneURL(instanceURL, cloneURL string) bool { + u1, err1 := url.Parse(instanceURL) + u2, err2 := url.Parse(cloneURL) + if err1 != nil || err2 != nil { + return false + } + + return u1.Host == u2.Host +} diff --git a/pkg/runner/step_action_remote.go b/pkg/runner/step_action_remote.go index b23ca197..0fe5d62b 100644 --- a/pkg/runner/step_action_remote.go +++ b/pkg/runner/step_action_remote.go @@ -109,17 +109,12 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor { } actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), sar.Step.UsesHash()) + token := getGitCloneToken(sar.getRunContext().Config, sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance)) gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{ - URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance), - Ref: sar.remoteAction.Ref, - Dir: actionDir, - Token: "", /* - Shouldn't provide token when cloning actions, - the token comes from the instance which triggered the task, - however, it might be not the same instance which provides actions. - For GitHub, they are the same, always github.com. - But for Gitea, tasks triggered by a.com can clone actions from b.com. - */ + URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance), + Ref: sar.remoteAction.Ref, + Dir: actionDir, + Token: token, OfflineMode: sar.RunContext.Config.ActionOfflineMode, InsecureSkipTLS: sar.cloneSkipTLS(), // For Gitea