refactor: move act/model and act/exprparser to actionslib (#1143)

Gitea needs the workflow model and the expression evaluator to parse workflows and to build the task payload this runner consumes, so today it depends on `gitea.com/gitea/runner` just for `act/model` and `act/exprparser`. Both packages now live in `gitea.dev/actionslib` (`pkg/model`, `pkg/exprparser`), the module both sides already share, and this repository consumes them from there.

### Changes

- `act/model` and `act/exprparser` are deleted, all imports point at `gitea.dev/actionslib/pkg/...`.
- New `act/ghcontext` package: the `GithubContext` helpers that need a git checkout on disk (`SetRef`, `SetSha`, `SetRepositoryAndOwner`) are runner only and would drag a git client plus the act context logger into the shared module, so they stay here as functions, with their tests. Only caller is `RunContext.getGithubContext`.
- `act/common.CartesianProduct` moved to the shared model package, `act/model` was its only user.
- `act/model/testdata/container-volumes` moved to `act/runner/testdata/container-volumes`, its only user is `runner_test.go`.
- `internal/pkg/client.UUIDHeader` / `TokenHeader` now alias `pkg/protocol`, so the header names cannot drift apart from Gitea.

### Notes

- No behaviour change intended: the moved files are unchanged apart from the import paths and the split described above.
- `go.mod` depends on the released `gitea.dev/actionslib v0.7.0`, which carries both https://gitea.com/gitea/actionslib/pulls/11 and the `model.UsesHash` port in https://gitea.com/gitea/actionslib/pulls/14 that `main` needs after https://gitea.com/gitea/runner/pulls/1150.
- Verified with `go build ./...`, `go vet ./...` and `go test ./act/... ./internal/...`; the docker based `act/runner` integration tests (`TestRunEvent`, `TestRunMatrixWithUserDefinedInclusions`) fail identically with and without this change in my environment.

Assisted-by: Codet:GPT-5.1-Codex
Reviewed-on: https://gitea.com/gitea/runner/pulls/1143
Reviewed-by: silverwind <[email protected]>
This commit is contained in:
Lunny Xiao
2026-08-08 00:29:15 +00:00
parent da9b559fb5
commit a8dcd5b67c
87 changed files with 247 additions and 5735 deletions
+1 -1
View File
@@ -23,8 +23,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/kballard/go-shellquote"
)
+1 -1
View File
@@ -18,8 +18,8 @@ import (
"time"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
+2 -1
View File
@@ -13,7 +13,8 @@ import (
"strings"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
)
func evaluateCompositeInputAndEnv(ctx context.Context, parent *RunContext, step actionStep) map[string]string {
+1 -1
View File
@@ -16,8 +16,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+2 -2
View File
@@ -9,9 +9,9 @@ import (
"time"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.yaml.in/yaml/v4"
+1 -1
View File
@@ -12,8 +12,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+14 -258
View File
@@ -7,7 +7,6 @@ package runner
import (
"bytes"
"context"
"errors"
"fmt"
"maps"
"path"
@@ -18,12 +17,12 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
_ "embed"
"github.com/rhysd/actionlint"
"gitea.dev/actionslib/pkg/expreval"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
"go.yaml.in/yaml/v4"
)
@@ -235,137 +234,16 @@ func (ee expressionEvaluator) evaluate(ctx context.Context, in string, defaultSt
return evaluated, err
}
func (ee expressionEvaluator) evaluateScalarYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
var in string
if err := node.Decode(&in); err != nil {
return nil, err
}
if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") {
return nil, nil //nolint:nilnil // pre-existing issue from nektos/act
}
res, err := ee.evaluateScalar(ctx, in)
if err != nil {
return nil, err
}
ret := &yaml.Node{}
if err := ret.Encode(res); err != nil {
return nil, err
}
return ret, err
}
func (ee expressionEvaluator) evaluateMappingYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
var ret *yaml.Node
// GitHub has this undocumented feature to merge maps, called insert directive
insertDirective := regexp.MustCompile(`\${{\s*insert\s*}}`)
for i := 0; i < len(node.Content)/2; i++ {
changed := func() error {
if ret == nil {
ret = &yaml.Node{}
if err := ret.Encode(node); err != nil {
return err
}
ret.Content = ret.Content[:i*2]
}
return nil
}
k := node.Content[i*2]
v := node.Content[i*2+1]
ev, err := ee.evaluateYamlNodeInternal(ctx, v)
if err != nil {
return nil, err
}
if ev != nil {
if err := changed(); err != nil {
return nil, err
}
} else {
ev = v
}
var sk string
// Merge the nested map of the insert directive
if k.Decode(&sk) == nil && insertDirective.MatchString(sk) {
if ev.Kind != yaml.MappingNode {
return nil, fmt.Errorf("failed to insert node %v into mapping %v unexpected type %v expected MappingNode", ev, node, ev.Kind)
}
if err := changed(); err != nil {
return nil, err
}
ret.Content = append(ret.Content, ev.Content...)
} else {
ek, err := ee.evaluateYamlNodeInternal(ctx, k)
if err != nil {
return nil, err
}
if ek != nil {
if err := changed(); err != nil {
return nil, err
}
} else {
ek = k
}
if ret != nil {
ret.Content = append(ret.Content, ek, ev)
}
}
}
return ret, nil
}
func (ee expressionEvaluator) evaluateSequenceYamlNode(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
var ret *yaml.Node
for i := 0; i < len(node.Content); i++ {
v := node.Content[i]
// Preserve nested sequences
wasseq := v.Kind == yaml.SequenceNode
ev, err := ee.evaluateYamlNodeInternal(ctx, v)
if err != nil {
return nil, err
}
if ev != nil {
if ret == nil {
ret = &yaml.Node{}
if err := ret.Encode(node); err != nil {
return nil, err
}
ret.Content = ret.Content[:i]
}
// GitHub has this undocumented feature to merge sequences / arrays
// We have a nested sequence via evaluation, merge the arrays
if ev.Kind == yaml.SequenceNode && !wasseq {
ret.Content = append(ret.Content, ev.Content...)
} else {
ret.Content = append(ret.Content, ev)
}
} else if ret != nil {
ret.Content = append(ret.Content, v)
}
}
return ret, nil
}
func (ee expressionEvaluator) evaluateYamlNodeInternal(ctx context.Context, node *yaml.Node) (*yaml.Node, error) {
switch node.Kind {
case yaml.ScalarNode:
return ee.evaluateScalarYamlNode(ctx, node)
case yaml.MappingNode:
return ee.evaluateMappingYamlNode(ctx, node)
case yaml.SequenceNode:
return ee.evaluateSequenceYamlNode(ctx, node)
default:
return nil, nil //nolint:nilnil // pre-existing issue from nektos/act
}
// shared returns the evaluation layer of the shared library, bound to this context so the
// evaluation of every single expression is still logged and masked here.
func (ee expressionEvaluator) shared(ctx context.Context) expreval.Evaluator {
return expreval.New(func(in string, defaultStatusCheck exprparser.DefaultStatusCheck) (any, error) {
return ee.evaluate(ctx, in, defaultStatusCheck)
})
}
func (ee expressionEvaluator) EvaluateYamlNode(ctx context.Context, node *yaml.Node) error {
ret, err := ee.evaluateYamlNodeInternal(ctx, node)
if err != nil {
return err
}
if ret != nil {
return ret.Decode(node)
}
return nil
return ee.shared(ctx).EvaluateYamlNode(node)
}
func (ee expressionEvaluator) Interpolate(ctx context.Context, in string) string {
@@ -377,138 +255,16 @@ func (ee expressionEvaluator) Interpolate(ctx context.Context, in string) string
return out
}
// interpolate evaluates every part on its own, so a malformed one cannot restructure its neighbours
func (ee expressionEvaluator) interpolate(ctx context.Context, in string) (string, error) {
parts, err := splitSubExpressions(in)
if err != nil {
return "", err
}
if len(parts) == 1 && !parts[0].isExpr {
return in, nil
}
var out strings.Builder
out.Grow(len(in))
for _, part := range parts {
if !part.isExpr {
out.WriteString(part.text)
continue
}
evaluated, err := ee.evaluate(ctx, part.text, exprparser.DefaultStatusCheckNone)
if err != nil {
return "", err
}
out.WriteString(exprparser.CoerceToString(evaluated))
}
return out.String(), nil
}
// evaluateScalar keeps the type of a lone expression, so `${{ fromJSON('[1,2]') }}` stays an array
func (ee expressionEvaluator) evaluateScalar(ctx context.Context, in string) (any, error) {
parts, err := splitSubExpressions(in)
if err != nil {
return nil, err
}
if len(parts) == 1 && parts[0].isExpr {
return ee.evaluate(ctx, parts[0].text, exprparser.DefaultStatusCheckNone)
}
return ee.interpolate(ctx, in)
return ee.shared(ctx).Interpolate(in)
}
// EvalBool evaluates an expression against given evaluator. An `if:` is an expression even without
// `${{ }}`, while literal text around one makes the whole value a string.
func EvalBool(ctx context.Context, evaluator ExpressionEvaluator, expr string, defaultStatusCheck exprparser.DefaultStatusCheck) (bool, error) {
parts, err := splitSubExpressions(expr)
if err != nil {
return false, err
}
if len(parts) == 1 {
evaluated, err := evaluator.evaluate(ctx, parts[0].text, defaultStatusCheck)
if err != nil {
return false, err
}
return exprparser.IsTruthy(evaluated), nil
}
// mixed content is a string, so the status check applies to it separately
if defaultStatusCheck != exprparser.DefaultStatusCheckNone && !callsStatusFunction(parts) {
status, err := evaluator.evaluate(ctx, "", defaultStatusCheck)
if err != nil {
return false, err
}
if !exprparser.IsTruthy(status) {
return false, nil
}
}
interpolated, err := evaluator.interpolate(ctx, expr)
if err != nil {
return false, err
}
return exprparser.IsTruthy(interpolated), nil
}
// callsStatusFunction reports whether any part calls a status function. A part that does not parse
// counts as one, so the evaluation reports it against the real values.
func callsStatusFunction(parts []exprPart) bool {
for _, part := range parts {
if !part.isExpr {
continue
}
// The lexer needs the closing `}}` that the scanner strips.
exprNode, err := actionlint.NewExprParser().Parse(actionlint.NewExprLexer(part.text + "}}"))
if err != nil || exprparser.CallsStatusFunction(exprNode) {
return true
}
}
return false
}
type exprPart struct {
text string
isExpr bool
}
// splitSubExpressions splits in the way GitHub's template reader does, leaving a value without a
// complete expression literal.
func splitSubExpressions(in string) ([]exprPart, error) {
if !strings.Contains(in, "${{") || !strings.Contains(in, "}}") {
return []exprPart{{text: in}}, nil
}
parts := make([]exprPart, 0, 2*strings.Count(in, "${{")+1)
for {
start := strings.Index(in, "${{")
if start < 0 {
if in != "" {
parts = append(parts, exprPart{text: in})
}
return parts, nil
}
if start > 0 {
parts = append(parts, exprPart{text: in[:start]})
}
rest := in[start+len("${{"):]
end := indexExprEnd(rest)
if end < 0 {
return nil, errors.New("unclosed expression")
}
parts = append(parts, exprPart{text: strings.TrimSpace(rest[:end]), isExpr: true})
in = rest[end+len("}}"):]
}
}
// indexExprEnd returns the offset of the `}}` ending an expression, or -1. A quote toggles string
// state, so a `}}` inside a string does not end it.
func indexExprEnd(in string) int {
inString := false
for i := range len(in) {
switch {
case in[i] == '\'':
inString = !inString
case !inString && in[i] == '}' && i+1 < len(in) && in[i+1] == '}':
return i
}
}
return -1
return expreval.New(func(in string, dsc exprparser.DefaultStatusCheck) (any, error) {
return evaluator.evaluate(ctx, in, dsc)
}).EvalBool(expr, defaultStatusCheck)
}
func getEvaluatorInputs(ctx context.Context, rc *RunContext, step step, ghc *model.GithubContext) map[string]any {
+2 -38
View File
@@ -9,9 +9,8 @@ import (
"strings"
"testing"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
assert "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
yaml "go.yaml.in/yaml/v4"
@@ -279,41 +278,6 @@ func TestInterpolate(t *testing.T) {
}
}
func TestSplitSubExpressions(t *testing.T) {
expr := func(text string) exprPart { return exprPart{text: text, isExpr: true} }
literal := func(text string) exprPart { return exprPart{text: text} }
for _, tt := range []struct {
in string
want []exprPart
}{
{"Hello World", []exprPart{literal("Hello World")}},
{"${{ true }}", []exprPart{expr("true")}},
{"${{ true }} ${{ false }}", []exprPart{expr("true"), literal(" "), expr("false")}},
{"Hello ${{ 'World' }}", []exprPart{literal("Hello "), expr("'World'")}},
// a quote toggles string state, so a `}}` inside a string does not end the expression
{"${{ '}}' }}", []exprPart{expr("'}}'")}},
{"${{ '''}}''' }}", []exprPart{expr("'''}}'''")}},
{"${{ '''' }}", []exprPart{expr("''''")}},
{`${{ fromJSON('"}}"') }}`, []exprPart{expr(`fromJSON('"}}"')`)}},
{`${{ fromJSON('"\"}}\""') }}`, []exprPart{expr(`fromJSON('"\"}}\""')`)}},
{`${{ fromJSON('"''}}"') }}`, []exprPart{expr(`fromJSON('"''}}"')`)}},
// without a complete literal the value stays text, as GitHub's template reader leaves it
{"${{ 1", []exprPart{literal("${{ 1")}},
// a malformed part stays one part, so it cannot restructure its neighbours
{"${{ 1) && (2 }}", []exprPart{expr("1) && (2")}},
} {
got, err := splitSubExpressions(tt.in)
require.NoError(t, err, tt.in)
assert.Equal(t, tt.want, got, tt.in)
}
for _, in := range []string{"${{ 'a' }} ${{ b", "${{ 'a }}"} {
_, err := splitSubExpressions(in)
assert.ErrorContains(t, err, "unclosed expression", in)
}
}
func TestGetEvaluatorInputsBoolean(t *testing.T) {
workflows := map[string]string{
"workflow_call": `
+3 -2
View File
@@ -23,8 +23,9 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
)
const maxJobSummaryBytes = 1024 * 1024
+1 -1
View File
@@ -22,8 +22,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
log "github.com/sirupsen/logrus"
logrustest "github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
+1 -1
View File
@@ -12,8 +12,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/sirupsen/logrus/hooks/test"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+1 -2
View File
@@ -6,8 +6,7 @@ package runner
import (
"testing"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"go.yaml.in/yaml/v4"
)
+2 -1
View File
@@ -16,7 +16,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
)
func newLocalReusableWorkflowExecutor(rc *RunContext) common.Executor {
+1 -1
View File
@@ -14,8 +14,8 @@ import (
"time"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/require"
)
+6 -5
View File
@@ -27,10 +27,11 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.com/gitea/runner/act/ghcontext"
"gitea.com/gitea/runner/internal/pkg/lock"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
"github.com/docker/cli/cli/compose/loader"
"github.com/docker/go-connections/nat"
"github.com/moby/moby/api/types/mount"
@@ -1355,12 +1356,12 @@ func (rc *RunContext) getGithubContext(ctx context.Context) *model.GithubContext
ghc.SetBaseAndHeadRef()
repoPath := rc.Config.Workdir
ghc.SetRepositoryAndOwner(ctx, rc.Config.GitHubInstance, rc.Config.RemoteName, repoPath)
ghcontext.SetRepositoryAndOwner(ctx, ghc, rc.Config.GitHubInstance, rc.Config.RemoteName, repoPath)
if ghc.Ref == "" {
ghc.SetRef(ctx, rc.Config.DefaultBranch, repoPath)
ghcontext.SetRef(ctx, ghc, rc.Config.DefaultBranch, repoPath)
}
if ghc.Sha == "" {
ghc.SetSha(ctx, repoPath)
ghcontext.SetSha(ctx, ghc, repoPath)
}
ghc.SetRefTypeAndName()
+2 -2
View File
@@ -17,9 +17,9 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
"github.com/docker/cli/cli/compose/loader"
log "github.com/sirupsen/logrus"
assert "github.com/stretchr/testify/assert"
+1 -1
View File
@@ -16,8 +16,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
docker_container "github.com/moby/moby/api/types/container"
log "github.com/sirupsen/logrus"
)
+2 -2
View File
@@ -19,8 +19,8 @@ import (
"time"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/joho/godotenv"
log "github.com/sirupsen/logrus"
assert "github.com/stretchr/testify/assert"
@@ -312,7 +312,7 @@ func TestRunEvent(t *testing.T) {
{workdir, "workflow_dispatch-scalar", "workflow_dispatch", "", platforms, secrets},
{workdir, "workflow_dispatch-scalar-composite-action", "workflow_dispatch", "", platforms, secrets},
{workdir, "job-needs-context-contains-result", "push", "", platforms, secrets},
{"../model/testdata", "container-volumes", "push", "", platforms, secrets},
{workdir, "container-volumes", "push", "", platforms, secrets},
{workdir, "path-handling", "push", "", platforms, secrets},
{workdir, "do-not-leak-step-env-in-composite", "push", "", platforms, secrets},
{workdir, "set-env-step-env-override", "push", "", platforms, secrets},
+3 -2
View File
@@ -15,8 +15,9 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/exprparser"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/exprparser"
"gitea.dev/actionslib/pkg/model"
)
type step interface {
+2 -1
View File
@@ -16,7 +16,8 @@ import (
"path/filepath"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
)
type stepActionLocal struct {
+1 -1
View File
@@ -13,8 +13,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"go.yaml.in/yaml/v4"
+1 -1
View File
@@ -18,8 +18,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
gogit "github.com/go-git/go-git/v5"
)
+1 -1
View File
@@ -19,8 +19,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+1 -1
View File
@@ -11,8 +11,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/kballard/go-shellquote"
)
+1 -1
View File
@@ -12,8 +12,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
+1 -1
View File
@@ -7,7 +7,7 @@ package runner
import (
"fmt"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
)
type stepFactory interface {
+1 -2
View File
@@ -7,8 +7,7 @@ package runner
import (
"testing"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
)
+1 -1
View File
@@ -15,8 +15,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/lookpath"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/kballard/go-shellquote"
"github.com/sirupsen/logrus"
yaml "go.yaml.in/yaml/v4"
+1 -1
View File
@@ -11,8 +11,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
+1 -1
View File
@@ -11,8 +11,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/container"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
)
+1 -1
View File
@@ -10,8 +10,8 @@ import (
"testing"
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
log "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
+19
View File
@@ -0,0 +1,19 @@
name: Job Container
on: push
jobs:
with-volumes:
runs-on: ubuntu-latest
container:
image: node:24-bookworm-slim
volumes:
- my_docker_volume:/path/to/volume
- /path/to/nonexist/directory
- /proc/sys/kernel/random/boot_id:/current/boot_id
steps:
- run: |
set -e
test -d /path/to/volume
test "$(cat /proc/sys/kernel/random/boot_id)" = "$(cat /current/boot_id)"
test -d /path/to/nonexist/directory
+2 -1
View File
@@ -13,7 +13,8 @@ import (
"gitea.com/gitea/runner/act/common"
"gitea.com/gitea/runner/act/common/git"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
)
// Actions bundle the @actions toolkit into their own JavaScript, and two of its lines keep it
+1 -2
View File
@@ -12,8 +12,7 @@ import (
"strings"
"testing"
"gitea.com/gitea/runner/act/model"
"gitea.dev/actionslib/pkg/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)