1
0
Fork 0
mirror of https://code.forgejo.org/forgejo/runner.git synced 2025-08-11 17:50:58 +00:00

feat: use hashed uses string as cache dir name (#186)

Port of https://gitea.com/gitea/act/pulls/117

Refs forgejo/act#100

Co-authored-by: Jason Song <i@wolfogre.com>
Reviewed-on: https://code.forgejo.org/forgejo/act/pulls/186
Reviewed-by: Michael Kriese <michael.kriese@gmx.de>
This commit is contained in:
earl-warren 2025-07-21 21:08:46 +00:00
parent 13ed94f5b7
commit a157d24741
4 changed files with 49 additions and 6 deletions

View file

@ -1,9 +1,12 @@
package model package model
import ( import (
"crypto/sha256"
"encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"path/filepath"
"reflect" "reflect"
"regexp" "regexp"
"strconv" "strconv"
@ -734,6 +737,12 @@ func (s *Step) Type() StepType {
return StepTypeUsesActionRemote return StepTypeUsesActionRemote
} }
func (s *Step) UsesHash() string {
hashBytes := sha256.Sum256([]byte(s.Uses))
hashString := hex.EncodeToString(hashBytes[:])
return filepath.Join(hashString[:2], hashString[2:])
}
// ReadWorkflow returns a list of jobs for a given workflow file reader // ReadWorkflow returns a list of jobs for a given workflow file reader
func ReadWorkflow(in io.Reader, validate bool) (*Workflow, error) { func ReadWorkflow(in io.Reader, validate bool) (*Workflow, error) {
if validate { if validate {

View file

@ -668,3 +668,37 @@ func TestReadWorkflow_WorkflowDispatchConfig(t *testing.T) {
Type: "choice", Type: "choice",
}, workflowDispatch.Inputs["logLevel"]) }, workflowDispatch.Inputs["logLevel"])
} }
func TestStepUsesHash(t *testing.T) {
type fields struct {
Uses string
}
tests := []struct {
name string
fields fields
want string
}{
{
name: "regular",
fields: fields{
Uses: "https://example.com/testa/testb@v3",
},
want: "e6/d70c1e8a4cc1e1cb02e32b3b60cc8dff319bb4fe5832fbc8b800711f18e7a2",
},
{
name: "empty",
fields: fields{
Uses: "",
},
want: "e3/b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
s := &Step{
Uses: tt.fields.Uses,
}
assert.Equalf(t, tt.want, s.UsesHash(), "UsesHash()")
})
}
}

View file

@ -551,7 +551,7 @@ func runPreStep(step actionStep) common.Executor {
var actionPath string var actionPath string
if _, ok := step.(*stepActionRemote); ok { if _, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses)) actionDir = filepath.Join(rc.ActionCacheDir(), stepModel.UsesHash())
} else { } else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = "" actionPath = ""
@ -602,7 +602,7 @@ func runPreStep(step actionStep) common.Executor {
var actionPath string var actionPath string
if _, ok := step.(*stepActionRemote); ok { if _, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses)) actionDir = filepath.Join(rc.ActionCacheDir(), stepModel.UsesHash())
} else { } else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = "" actionPath = ""
@ -689,7 +689,7 @@ func runPostStep(step actionStep) common.Executor {
var actionPath string var actionPath string
if _, ok := step.(*stepActionRemote); ok { if _, ok := step.(*stepActionRemote); ok {
actionPath = newRemoteAction(stepModel.Uses).Path actionPath = newRemoteAction(stepModel.Uses).Path
actionDir = fmt.Sprintf("%s/%s", rc.ActionCacheDir(), safeFilename(stepModel.Uses)) actionDir = filepath.Join(rc.ActionCacheDir(), stepModel.UsesHash())
} else { } else {
actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses) actionDir = filepath.Join(rc.Config.Workdir, stepModel.Uses)
actionPath = "" actionPath = ""

View file

@ -108,7 +108,7 @@ func (sar *stepActionRemote) prepareActionExecutor() common.Executor {
return err return err
} }
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) actionDir := filepath.Join(sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{ gitClone := stepActionRemoteNewCloneExecutor(git.NewGitCloneExecutorInput{
URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance), URL: sar.remoteAction.CloneURL(sar.RunContext.Config.DefaultActionInstance),
Ref: sar.remoteAction.Ref, Ref: sar.remoteAction.Ref,
@ -177,7 +177,7 @@ func (sar *stepActionRemote) main() common.Executor {
return sar.RunContext.JobContainer.CopyDir(copyToPath, sar.RunContext.Config.Workdir+string(filepath.Separator)+".", sar.RunContext.Config.UseGitIgnore)(ctx) return sar.RunContext.JobContainer.CopyDir(copyToPath, sar.RunContext.Config.Workdir+string(filepath.Separator)+".", sar.RunContext.Config.UseGitIgnore)(ctx)
} }
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) actionDir := filepath.Join(sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
return sar.runAction(sar, actionDir, sar.remoteAction)(ctx) return sar.runAction(sar, actionDir, sar.remoteAction)(ctx)
}), }),
@ -236,7 +236,7 @@ func (sar *stepActionRemote) getActionModel() *model.Action {
func (sar *stepActionRemote) getCompositeRunContext(ctx context.Context) *RunContext { func (sar *stepActionRemote) getCompositeRunContext(ctx context.Context) *RunContext {
if sar.compositeRunContext == nil { if sar.compositeRunContext == nil {
actionDir := fmt.Sprintf("%s/%s", sar.RunContext.ActionCacheDir(), safeFilename(sar.Step.Uses)) actionDir := filepath.Join(sar.RunContext.ActionCacheDir(), sar.Step.UsesHash())
actionLocation := path.Join(actionDir, sar.remoteAction.Path) actionLocation := path.Join(actionDir, sar.remoteAction.Path)
_, containerActionDir := getContainerActionPaths(sar.getStepModel(), actionLocation, sar.RunContext) _, containerActionDir := getContainerActionPaths(sar.getStepModel(), actionLocation, sar.RunContext)