mirror of
https://code.forgejo.org/forgejo/runner.git
synced 2025-10-10 19:32:04 +00:00
Merge pull request 'PR#3. Reducing the delta between Nektos/Act and Forgejo/Act' (#117) from achyrva/act:nektos-into-forgejo-0 into main
Reviewed-on: https://code.forgejo.org/forgejo/act/pulls/117 Reviewed-by: earl-warren <earl-warren@noreply.code.forgejo.org> Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
This commit is contained in:
commit
ba102368d3
4 changed files with 110 additions and 50 deletions
|
@ -6,7 +6,6 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"path"
|
"path"
|
||||||
|
@ -43,17 +42,7 @@ func (c GoGitActionCache) Fetch(ctx context.Context, cacheDir, url, ref, token s
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
branchName := hex.EncodeToString(tmpBranch)
|
branchName := hex.EncodeToString(tmpBranch)
|
||||||
var refSpec config.RefSpec
|
|
||||||
spec := config.RefSpec(ref + ":" + branchName)
|
|
||||||
tagOrSha := false
|
|
||||||
if spec.IsExactSHA1() {
|
|
||||||
refSpec = spec
|
|
||||||
} else if strings.HasPrefix(ref, "refs/") {
|
|
||||||
refSpec = config.RefSpec(ref + ":refs/heads/" + branchName)
|
|
||||||
} else {
|
|
||||||
tagOrSha = true
|
|
||||||
refSpec = config.RefSpec("refs/*/" + ref + ":refs/heads/*/" + branchName)
|
|
||||||
}
|
|
||||||
var auth transport.AuthMethod
|
var auth transport.AuthMethod
|
||||||
if token != "" {
|
if token != "" {
|
||||||
auth = &http.BasicAuth{
|
auth = &http.BasicAuth{
|
||||||
|
@ -71,35 +60,17 @@ func (c GoGitActionCache) Fetch(ctx context.Context, cacheDir, url, ref, token s
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
if refs, err := gogitrepo.References(); err == nil {
|
_ = gogitrepo.DeleteBranch(branchName)
|
||||||
_ = refs.ForEach(func(r *plumbing.Reference) error {
|
|
||||||
if strings.Contains(r.Name().String(), branchName) {
|
|
||||||
return gogitrepo.DeleteBranch(r.Name().String())
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
if err := remote.FetchContext(ctx, &git.FetchOptions{
|
if err := remote.FetchContext(ctx, &git.FetchOptions{
|
||||||
RefSpecs: []config.RefSpec{
|
RefSpecs: []config.RefSpec{
|
||||||
refSpec,
|
config.RefSpec(ref + ":" + branchName),
|
||||||
},
|
},
|
||||||
Auth: auth,
|
Auth: auth,
|
||||||
Force: true,
|
Force: true,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
if tagOrSha && errors.Is(err, git.NoErrAlreadyUpToDate) {
|
|
||||||
return "", fmt.Errorf("couldn't find remote ref \"%s\"", ref)
|
|
||||||
}
|
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if tagOrSha {
|
|
||||||
for _, prefix := range []string{"refs/heads/tags/", "refs/heads/heads/"} {
|
|
||||||
hash, err := gogitrepo.ResolveRevision(plumbing.Revision(prefix + branchName))
|
|
||||||
if err == nil {
|
|
||||||
return hash.String(), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hash, err := gogitrepo.ResolveRevision(plumbing.Revision(branchName))
|
hash, err := gogitrepo.ResolveRevision(plumbing.Revision(branchName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
|
|
41
act/runner/action_cache_offline_mode.go
Normal file
41
act/runner/action_cache_offline_mode.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package runner
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"io"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
git "github.com/go-git/go-git/v5"
|
||||||
|
"github.com/go-git/go-git/v5/plumbing"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GoGitActionCacheOfflineMode struct {
|
||||||
|
Parent GoGitActionCache
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GoGitActionCacheOfflineMode) Fetch(ctx context.Context, cacheDir, url, ref, token string) (string, error) {
|
||||||
|
sha, fetchErr := c.Parent.Fetch(ctx, cacheDir, url, ref, token)
|
||||||
|
gitPath := path.Join(c.Parent.Path, safeFilename(cacheDir)+".git")
|
||||||
|
gogitrepo, err := git.PlainOpen(gitPath)
|
||||||
|
if err != nil {
|
||||||
|
return "", fetchErr
|
||||||
|
}
|
||||||
|
refName := plumbing.ReferenceName("refs/action-cache-offline/" + ref)
|
||||||
|
r, err := gogitrepo.Reference(refName, true)
|
||||||
|
if fetchErr == nil {
|
||||||
|
if err != nil || sha != r.Hash().String() {
|
||||||
|
if err == nil {
|
||||||
|
refName = r.Name()
|
||||||
|
}
|
||||||
|
ref := plumbing.NewHashReference(refName, plumbing.NewHash(sha))
|
||||||
|
_ = gogitrepo.Storer.SetReference(ref)
|
||||||
|
}
|
||||||
|
} else if err == nil {
|
||||||
|
return r.Hash().String(), nil
|
||||||
|
}
|
||||||
|
return sha, fetchErr
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c GoGitActionCacheOfflineMode) GetTarArchive(ctx context.Context, cacheDir, sha, includePrefix string) (io.ReadCloser, error) {
|
||||||
|
return c.Parent.GetTarArchive(ctx, cacheDir, sha, includePrefix)
|
||||||
|
}
|
|
@ -18,20 +18,60 @@ func TestActionCache(t *testing.T) {
|
||||||
Path: os.TempDir(),
|
Path: os.TempDir(),
|
||||||
}
|
}
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
sha, err := cache.Fetch(ctx, "christopherhx/script", "https://github.com/christopherhx/script", "main", "")
|
cacheDir := "nektos/act-test-actions"
|
||||||
a.NoError(err)
|
repo := "https://github.com/nektos/act-test-actions"
|
||||||
a.NotEmpty(sha)
|
refs := []struct {
|
||||||
atar, err := cache.GetTarArchive(ctx, "christopherhx/script", sha, "node_modules")
|
Name string
|
||||||
a.NoError(err)
|
CacheDir string
|
||||||
a.NotEmpty(atar)
|
Repo string
|
||||||
|
Ref string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
Name: "Fetch Branch Name",
|
||||||
|
CacheDir: cacheDir,
|
||||||
|
Repo: repo,
|
||||||
|
Ref: "main",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Fetch Branch Name Absolutely",
|
||||||
|
CacheDir: cacheDir,
|
||||||
|
Repo: repo,
|
||||||
|
Ref: "refs/heads/main",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Fetch HEAD",
|
||||||
|
CacheDir: cacheDir,
|
||||||
|
Repo: repo,
|
||||||
|
Ref: "HEAD",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Fetch Sha",
|
||||||
|
CacheDir: cacheDir,
|
||||||
|
Repo: repo,
|
||||||
|
Ref: "de984ca37e4df4cb9fd9256435a3b82c4a2662b1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, c := range refs {
|
||||||
|
t.Run(c.Name, func(t *testing.T) {
|
||||||
|
sha, err := cache.Fetch(ctx, c.CacheDir, c.Repo, c.Ref, "")
|
||||||
|
if !a.NoError(err) || !a.NotEmpty(sha) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
atar, err := cache.GetTarArchive(ctx, c.CacheDir, sha, "js")
|
||||||
|
if !a.NoError(err) || !a.NotEmpty(atar) {
|
||||||
|
return
|
||||||
|
}
|
||||||
mytar := tar.NewReader(atar)
|
mytar := tar.NewReader(atar)
|
||||||
th, err := mytar.Next()
|
th, err := mytar.Next()
|
||||||
a.NoError(err)
|
if !a.NoError(err) || !a.NotEqual(0, th.Size) {
|
||||||
a.NotEqual(0, th.Size)
|
return
|
||||||
|
}
|
||||||
buf := &bytes.Buffer{}
|
buf := &bytes.Buffer{}
|
||||||
// G110: Potential DoS vulnerability via decompression bomb (gosec)
|
// G110: Potential DoS vulnerability via decompression bomb (gosec)
|
||||||
_, err = io.Copy(buf, mytar)
|
_, err = io.Copy(buf, mytar)
|
||||||
a.NoError(err)
|
a.NoError(err)
|
||||||
str := buf.String()
|
str := buf.String()
|
||||||
a.NotEmpty(str)
|
a.NotEmpty(str)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -617,10 +617,18 @@ func newRunCommand(ctx context.Context, input *Input) func(*cobra.Command, []str
|
||||||
ContainerNetworkMode: docker_container.NetworkMode(input.networkName),
|
ContainerNetworkMode: docker_container.NetworkMode(input.networkName),
|
||||||
}
|
}
|
||||||
if input.useNewActionCache {
|
if input.useNewActionCache {
|
||||||
|
if input.actionOfflineMode {
|
||||||
|
config.ActionCache = &runner.GoGitActionCacheOfflineMode{
|
||||||
|
Parent: runner.GoGitActionCache{
|
||||||
|
Path: config.ActionCacheDir,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
config.ActionCache = &runner.GoGitActionCache{
|
config.ActionCache = &runner.GoGitActionCache{
|
||||||
Path: config.ActionCacheDir,
|
Path: config.ActionCacheDir,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
r, err := runner.New(config)
|
r, err := runner.New(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue