Support uses http(s)://host/owner/repo as actions (#14)
Examples: ```yaml jobs: my_first_job: steps: - name: My first step uses: https://gitea.com/actions/heroku@main - name: My second step uses: http://example.com/actions/heroku@v2.0.1 ``` Reviewed-on: https://gitea.com/gitea/act/pulls/14 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: Jason Song <i@wolfogre.com> Co-committed-by: Jason Song <i@wolfogre.com>
This commit is contained in:
parent
4b99ed8916
commit
dca7801682
2 changed files with 120 additions and 5 deletions
|
@ -44,8 +44,6 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||||
return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses)
|
return fmt.Errorf("Expected format {org}/{repo}[/path]@ref. Actual '%s' Input string was not in a correct format", sar.Step.Uses)
|
||||||
}
|
}
|
||||||
|
|
||||||
sar.remoteAction.URL = sar.RunContext.Config.DefaultActionInstance
|
|
||||||
|
|
||||||
github := sar.getGithubContext(ctx)
|
github := sar.getGithubContext(ctx)
|
||||||
if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {
|
if sar.remoteAction.IsCheckout() && isLocalCheckout(github, sar.Step) && !sar.RunContext.Config.NoSkipCheckout {
|
||||||
common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied")
|
common.Logger(ctx).Debugf("Skipping local actions/checkout because workdir was already copied")
|
||||||
|
@ -61,7 +59,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
|
||||||
|
|
||||||
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-"))
|
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), strings.ReplaceAll(sar.Step.Uses, "/", "-"))
|
||||||
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
|
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
|
||||||
URL: sar.remoteAction.CloneURL(),
|
URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance),
|
||||||
Ref: sar.remoteAction.Ref,
|
Ref: sar.remoteAction.Ref,
|
||||||
Dir: actionDir,
|
Dir: actionDir,
|
||||||
Token: "", /*
|
Token: "", /*
|
||||||
|
@ -215,8 +213,11 @@ type remoteAction struct {
|
||||||
Ref string
|
Ref string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ra *remoteAction) CloneURL() string {
|
func (ra *remoteAction) CloneURL(defaultURL string) string {
|
||||||
u := ra.URL
|
u := ra.URL
|
||||||
|
if u == "" {
|
||||||
|
u = defaultURL
|
||||||
|
}
|
||||||
if !strings.HasPrefix(u, "http://") && !strings.HasPrefix(u, "https://") {
|
if !strings.HasPrefix(u, "http://") && !strings.HasPrefix(u, "https://") {
|
||||||
u = "https://" + u
|
u = "https://" + u
|
||||||
}
|
}
|
||||||
|
@ -231,6 +232,26 @@ func (ra *remoteAction) IsCheckout() bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func newRemoteAction(action string) *remoteAction {
|
func newRemoteAction(action string) *remoteAction {
|
||||||
|
// support http(s)://host/owner/repo@v3
|
||||||
|
for _, schema := range []string{"https://", "http://"} {
|
||||||
|
if strings.HasPrefix(action, schema) {
|
||||||
|
splits := strings.SplitN(strings.TrimPrefix(action, schema), "/", 2)
|
||||||
|
if len(splits) != 2 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ret := parseAction(splits[1])
|
||||||
|
if ret == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
ret.URL = schema + splits[0]
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseAction(action)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseAction(action string) *remoteAction {
|
||||||
// GitHub's document[^] describes:
|
// GitHub's document[^] describes:
|
||||||
// > We strongly recommend that you include the version of
|
// > We strongly recommend that you include the version of
|
||||||
// > the action you are using by specifying a Git ref, SHA, or Docker tag number.
|
// > the action you are using by specifying a Git ref, SHA, or Docker tag number.
|
||||||
|
@ -246,6 +267,6 @@ func newRemoteAction(action string) *remoteAction {
|
||||||
Repo: matches[2],
|
Repo: matches[2],
|
||||||
Path: matches[4],
|
Path: matches[4],
|
||||||
Ref: matches[6],
|
Ref: matches[6],
|
||||||
URL: "github.com",
|
URL: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -623,3 +623,97 @@ func TestStepActionRemotePost(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_newRemoteAction(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
action string
|
||||||
|
want *remoteAction
|
||||||
|
wantCloneURL string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
action: "actions/heroku@main",
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "heroku",
|
||||||
|
Path: "",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "https://github.com/actions/heroku",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "actions/aws/ec2@main",
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "aws",
|
||||||
|
Path: "ec2",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "https://github.com/actions/aws",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "./.github/actions/my-action", // it's valid for GitHub, but act don't support it
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "docker://alpine:3.8", // it's valid for GitHub, but act don't support it
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "https://gitea.com/actions/heroku@main", // it's invalid for GitHub, but gitea supports it
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "https://gitea.com",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "heroku",
|
||||||
|
Path: "",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "https://gitea.com/actions/heroku",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "https://gitea.com/actions/aws/ec2@main", // it's invalid for GitHub, but gitea supports it
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "https://gitea.com",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "aws",
|
||||||
|
Path: "ec2",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "https://gitea.com/actions/aws",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "http://gitea.com/actions/heroku@main", // it's invalid for GitHub, but gitea supports it
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "http://gitea.com",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "heroku",
|
||||||
|
Path: "",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "http://gitea.com/actions/heroku",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: "http://gitea.com/actions/aws/ec2@main", // it's invalid for GitHub, but gitea supports it
|
||||||
|
want: &remoteAction{
|
||||||
|
URL: "http://gitea.com",
|
||||||
|
Org: "actions",
|
||||||
|
Repo: "aws",
|
||||||
|
Path: "ec2",
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
wantCloneURL: "http://gitea.com/actions/aws",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.action, func(t *testing.T) {
|
||||||
|
got := newRemoteAction(tt.action)
|
||||||
|
assert.Equalf(t, tt.want, got, "newRemoteAction(%v)", tt.action)
|
||||||
|
cloneURL := ""
|
||||||
|
if got != nil {
|
||||||
|
cloneURL = got.CloneURL("github.com")
|
||||||
|
}
|
||||||
|
assert.Equalf(t, tt.wantCloneURL, cloneURL, "newRemoteAction(%v).CloneURL()", tt.action)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue