Support reusable workflow (#34)
Fix https://gitea.com/gitea/act_runner/issues/80 Fix https://gitea.com/gitea/act_runner/issues/85 To support reusable workflows, I made some improvements: - read `yml` files from both `.gitea/workflows` and `.github/workflows` - clone repository for local reusable workflows because the runner doesn't have the code in its local directory - fix the incorrect clone url like `https://https://gitea.com` Co-authored-by: Jason Song <i@wolfogre.com> Reviewed-on: https://gitea.com/gitea/act/pulls/34 Reviewed-by: Jason Song <i@wolfogre.com> Co-authored-by: Zettat123 <zettat123@gmail.com> Co-committed-by: Zettat123 <zettat123@gmail.com>
This commit is contained in:
parent
2eb4de02ee
commit
5e76853b55
2 changed files with 57 additions and 8 deletions
|
@ -506,8 +506,12 @@ func (j JobType) String() string {
|
|||
func (j *Job) Type() JobType {
|
||||
if strings.HasPrefix(j.Uses, "./.github/workflows") && (strings.HasSuffix(j.Uses, ".yml") || strings.HasSuffix(j.Uses, ".yaml")) {
|
||||
return JobTypeReusableWorkflowLocal
|
||||
} else if strings.HasPrefix(j.Uses, "./.gitea/workflows") && (strings.HasSuffix(j.Uses, ".yml") || strings.HasSuffix(j.Uses, ".yaml")) {
|
||||
return JobTypeReusableWorkflowLocal
|
||||
} else if !strings.HasPrefix(j.Uses, "./") && strings.Contains(j.Uses, ".github/workflows") && (strings.Contains(j.Uses, ".yml@") || strings.Contains(j.Uses, ".yaml@")) {
|
||||
return JobTypeReusableWorkflowRemote
|
||||
} else if !strings.HasPrefix(j.Uses, "./") && strings.Contains(j.Uses, ".gitea/workflows") && (strings.Contains(j.Uses, ".yml@") || strings.Contains(j.Uses, ".yaml@")) {
|
||||
return JobTypeReusableWorkflowRemote
|
||||
}
|
||||
return JobTypeDefault
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"os"
|
||||
"path"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/nektos/act/pkg/common"
|
||||
|
@ -16,15 +17,14 @@ import (
|
|||
)
|
||||
|
||||
func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
return newReusableWorkflowExecutor(rc, rc.Config.Workdir, rc.Run.Job().Uses)
|
||||
}
|
||||
// ./.gitea/workflows/wf.yml -> .gitea/workflows/wf.yml
|
||||
trimmedUses := strings.TrimPrefix(rc.Run.Job().Uses, "./")
|
||||
// uses string format is {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}
|
||||
uses := fmt.Sprintf("%s/%s@%s", rc.Config.PresetGitHubContext.Repository, trimmedUses, rc.Config.PresetGitHubContext.Sha)
|
||||
|
||||
func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
uses := rc.Run.Job().Uses
|
||||
|
||||
remoteReusableWorkflow := newRemoteReusableWorkflow(uses)
|
||||
remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(uses)
|
||||
if remoteReusableWorkflow == nil {
|
||||
return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.github/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses))
|
||||
return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses))
|
||||
}
|
||||
remoteReusableWorkflow.URL = rc.Config.GitHubInstance
|
||||
|
||||
|
@ -32,7 +32,24 @@ func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
|||
|
||||
return common.NewPipelineExecutor(
|
||||
newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir)),
|
||||
newReusableWorkflowExecutor(rc, workflowDir, fmt.Sprintf("./.github/workflows/%s", remoteReusableWorkflow.Filename)),
|
||||
newReusableWorkflowExecutor(rc, workflowDir, remoteReusableWorkflow.FilePath()),
|
||||
)
|
||||
}
|
||||
|
||||
func newRemoteReusableWorkflowExecutor(rc *RunContext) common.Executor {
|
||||
uses := rc.Run.Job().Uses
|
||||
|
||||
remoteReusableWorkflow := newRemoteReusableWorkflowWithPlat(uses)
|
||||
if remoteReusableWorkflow == nil {
|
||||
return common.NewErrorExecutor(fmt.Errorf("expected format {owner}/{repo}/.{git_platform}/workflows/{filename}@{ref}. Actual '%s' Input string was not in a correct format", uses))
|
||||
}
|
||||
remoteReusableWorkflow.URL = rc.Config.GitHubInstance
|
||||
|
||||
workflowDir := fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(uses))
|
||||
|
||||
return common.NewPipelineExecutor(
|
||||
newMutexExecutor(cloneIfRequired(rc, *remoteReusableWorkflow, workflowDir)),
|
||||
newReusableWorkflowExecutor(rc, workflowDir, remoteReusableWorkflow.FilePath()),
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -105,12 +122,40 @@ type remoteReusableWorkflow struct {
|
|||
Repo string
|
||||
Filename string
|
||||
Ref string
|
||||
|
||||
GitPlatform string
|
||||
}
|
||||
|
||||
func (r *remoteReusableWorkflow) CloneURL() string {
|
||||
// In Gitea, r.URL always has the protocol prefix, we don't need to add extra prefix in this case.
|
||||
if strings.HasPrefix(r.URL, "http://") || strings.HasPrefix(r.URL, "https://") {
|
||||
return fmt.Sprintf("%s/%s/%s", r.URL, r.Org, r.Repo)
|
||||
}
|
||||
return fmt.Sprintf("https://%s/%s/%s", r.URL, r.Org, r.Repo)
|
||||
}
|
||||
|
||||
func (r *remoteReusableWorkflow) FilePath() string {
|
||||
return fmt.Sprintf("./.%s/workflows/%s", r.GitPlatform, r.Filename)
|
||||
}
|
||||
|
||||
func newRemoteReusableWorkflowWithPlat(uses string) *remoteReusableWorkflow {
|
||||
// GitHub docs:
|
||||
// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses
|
||||
r := regexp.MustCompile(`^([^/]+)/([^/]+)/\.([^/]+)/workflows/([^@]+)@(.*)$`)
|
||||
matches := r.FindStringSubmatch(uses)
|
||||
if len(matches) != 6 {
|
||||
return nil
|
||||
}
|
||||
return &remoteReusableWorkflow{
|
||||
Org: matches[1],
|
||||
Repo: matches[2],
|
||||
GitPlatform: matches[3],
|
||||
Filename: matches[4],
|
||||
Ref: matches[5],
|
||||
}
|
||||
}
|
||||
|
||||
// deprecated: use newRemoteReusableWorkflowWithPlat
|
||||
func newRemoteReusableWorkflow(uses string) *remoteReusableWorkflow {
|
||||
// GitHub docs:
|
||||
// https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_iduses
|
||||
|
|
Loading…
Reference in a new issue