mirror of
https://gitea.com/gitea/act_runner.git
synced 2026-03-20 03:46:09 +08:00
chore(deps): update act to v0.261.8 (#791)
## Summary - Update `gitea.com/gitea/act` from pseudo-version `v0.261.7-0.20251202193638-5417d3ac6742` to `v0.261.8` - Update yaml import in `workflow.go` from `gopkg.in/yaml.v3` to `go.yaml.in/yaml/v4` to match act's yaml v4 migration - Add tests to verify yaml/v4 upgrade works correctly ## Changes included in act v0.261.8 - Recover from panics in parallel executor workers ([gitea/act#153](https://gitea.com/gitea/act/pulls/153)) - Fix max-parallel support for matrix jobs ([gitea/act#150](https://gitea.com/gitea/act/pulls/150)) - Fix yaml with prefixed newline broken setjob + yaml v4 ([gitea/act#144](https://gitea.com/gitea/act/pulls/144)) - Fixed typo ([gitea/act#151](https://gitea.com/gitea/act/pulls/151)) ## Tests added - **`Test_generateWorkflow`**: 7 new cases (was 1), covering: no needs, needs as list, workflow env/triggers, container+services, matrix strategy, special YAML characters, and invalid YAML error handling - **`Test_yamlV4NodeRoundTrip`**: Directly exercises `go.yaml.in/yaml/v4` — `yaml.Node` construction, marshal/unmarshal round-trip, and node kind constants Fixes: https://gitea.com/gitea/act_runner/issues/371 Fixes: https://gitea.com/gitea/act_runner/issues/772 Reviewed-on: https://gitea.com/gitea/act_runner/pulls/791 Reviewed-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: silverwind <me@silverwind.io> Co-committed-by: silverwind <me@silverwind.io>
This commit is contained in:
4
go.mod
4
go.mod
@@ -21,6 +21,8 @@ require (
|
|||||||
gotest.tools/v3 v3.5.1
|
gotest.tools/v3 v3.5.1
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require go.yaml.in/yaml/v4 v4.0.0-rc.2
|
||||||
|
|
||||||
require (
|
require (
|
||||||
cyphar.com/go-pathrs v0.2.1 // indirect
|
cyphar.com/go-pathrs v0.2.1 // indirect
|
||||||
dario.cat/mergo v1.0.0 // indirect
|
dario.cat/mergo v1.0.0 // indirect
|
||||||
@@ -100,7 +102,7 @@ require (
|
|||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
||||||
replace github.com/nektos/act => gitea.com/gitea/act v0.261.7-0.20251202193638-5417d3ac6742
|
replace github.com/nektos/act => gitea.com/gitea/act v0.261.8
|
||||||
|
|
||||||
replace github.com/go-git/go-git/v5 => github.com/go-git/go-git/v5 v5.16.2
|
replace github.com/go-git/go-git/v5 => github.com/go-git/go-git/v5 v5.16.2
|
||||||
|
|
||||||
|
|||||||
6
go.sum
6
go.sum
@@ -8,8 +8,8 @@ cyphar.com/go-pathrs v0.2.1 h1:9nx1vOgwVvX1mNBWDu93+vaceedpbsDqo+XuBGL40b8=
|
|||||||
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
|
cyphar.com/go-pathrs v0.2.1/go.mod h1:y8f1EMG7r+hCuFf/rXsKqMJrJAUoADZGNh5/vZPKcGc=
|
||||||
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
|
||||||
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
|
||||||
gitea.com/gitea/act v0.261.7-0.20251202193638-5417d3ac6742 h1:ulcquQluJbmNASkh6ina70LvcHEa9eWYfQ+DeAZ0VEE=
|
gitea.com/gitea/act v0.261.8 h1:rUWB5GOZOubfe2VteKb7XP3HRIbcW3UUmfh7bVAgQcA=
|
||||||
gitea.com/gitea/act v0.261.7-0.20251202193638-5417d3ac6742/go.mod h1:Pg5C9kQY1CEA3QjthjhlrqOC/QOT5NyWNjOjRHw23Ok=
|
gitea.com/gitea/act v0.261.8/go.mod h1:lTp4136rwbZiZS3ZVQeHCvd4qRAZ7LYeiRBqOSdMY/4=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24 h1:bvDV9vkmnHYOMsOr4WLk+Vo07yKIzd94sVoIqshQ4bU=
|
||||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
github.com/AdaLogics/go-fuzz-headers v0.0.0-20230811130428-ced1acdcaa24/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
|
||||||
@@ -227,6 +227,8 @@ go.opentelemetry.io/otel/trace v1.28.0 h1:GhQ9cUuQGmNDd5BTCP2dAvv75RdMxEfTmYejp+
|
|||||||
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI=
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I=
|
||||||
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM=
|
||||||
|
go.yaml.in/yaml/v4 v4.0.0-rc.2 h1:/FrI8D64VSr4HtGIlUtlFMGsm7H7pWTbj6vOLVZcA6s=
|
||||||
|
go.yaml.in/yaml/v4 v4.0.0-rc.2/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0=
|
||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
|
|
||||||
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
||||||
"github.com/nektos/act/pkg/model"
|
"github.com/nektos/act/pkg/model"
|
||||||
"gopkg.in/yaml.v3"
|
"go.yaml.in/yaml/v4"
|
||||||
)
|
)
|
||||||
|
|
||||||
func generateWorkflow(task *runnerv1.Task) (*model.Workflow, string, error) {
|
func generateWorkflow(task *runnerv1.Task) (*model.Workflow, string, error) {
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
||||||
"github.com/nektos/act/pkg/model"
|
"github.com/nektos/act/pkg/model"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
"go.yaml.in/yaml/v4"
|
||||||
"gotest.tools/v3/assert"
|
"gotest.tools/v3/assert"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -62,13 +63,267 @@ jobs:
|
|||||||
want1: "job9",
|
want1: "job9",
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "no needs",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Simple workflow
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: echo "hello"
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
job := wf.GetJob("test")
|
||||||
|
assert.DeepEqual(t, job.Needs(), []string{})
|
||||||
|
assert.Equal(t, len(job.Steps), 2)
|
||||||
|
},
|
||||||
|
want1: "test",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "needs list",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Workflow with list needs
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
needs: [build, test, lint]
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "deploying"
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{
|
||||||
|
"build": {
|
||||||
|
Outputs: map[string]string{},
|
||||||
|
Result: runnerv1.Result_RESULT_SUCCESS,
|
||||||
|
},
|
||||||
|
"test": {
|
||||||
|
Outputs: map[string]string{
|
||||||
|
"coverage": "80%",
|
||||||
|
},
|
||||||
|
Result: runnerv1.Result_RESULT_SUCCESS,
|
||||||
|
},
|
||||||
|
"lint": {
|
||||||
|
Outputs: map[string]string{},
|
||||||
|
Result: runnerv1.Result_RESULT_FAILURE,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
job := wf.GetJob("deploy")
|
||||||
|
needs := job.Needs()
|
||||||
|
assert.DeepEqual(t, needs, []string{"build", "lint", "test"})
|
||||||
|
assert.Equal(t, wf.Jobs["test"].Outputs["coverage"], "80%")
|
||||||
|
assert.Equal(t, wf.Jobs["lint"].Result, "failure")
|
||||||
|
},
|
||||||
|
want1: "deploy",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "workflow env and defaults",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Complex workflow
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main, develop]
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize]
|
||||||
|
|
||||||
|
env:
|
||||||
|
NODE_ENV: production
|
||||||
|
CI: "true"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
env:
|
||||||
|
BUILD_TYPE: release
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: "18"
|
||||||
|
- run: npm ci
|
||||||
|
- run: npm run build
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
assert.Equal(t, wf.Name, "Complex workflow")
|
||||||
|
assert.Equal(t, wf.Env["NODE_ENV"], "production")
|
||||||
|
assert.Equal(t, wf.Env["CI"], "true")
|
||||||
|
job := wf.GetJob("build")
|
||||||
|
assert.Equal(t, len(job.Steps), 4)
|
||||||
|
},
|
||||||
|
want1: "build",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job with container and services",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Integration tests
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
integration:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: node:18
|
||||||
|
services:
|
||||||
|
postgres:
|
||||||
|
image: postgres:15
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: npm test
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
job := wf.GetJob("integration")
|
||||||
|
container := job.Container()
|
||||||
|
assert.Equal(t, container.Image, "node:18")
|
||||||
|
assert.Equal(t, job.Services["postgres"].Image, "postgres:15")
|
||||||
|
},
|
||||||
|
want1: "integration",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "job with matrix strategy",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Matrix build
|
||||||
|
on: push
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
go-version: ["1.21", "1.22"]
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- run: go test ./...
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
job := wf.GetJob("test")
|
||||||
|
matrixes, err := job.GetMatrixes()
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, len(matrixes), 2)
|
||||||
|
},
|
||||||
|
want1: "test",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "special yaml characters in values",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte("name: \"Special: characters & test\"\non: push\n\njobs:\n test:\n runs-on: ubuntu-latest\n steps:\n - run: 'echo \"hello: world\"'\n - run: 'echo \"quotes & ampersands\"'\n - run: |\n echo \"multiline\"\n echo \"script\"\n"),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: func(t *testing.T, wf *model.Workflow) {
|
||||||
|
assert.Equal(t, wf.Name, "Special: characters & test")
|
||||||
|
job := wf.GetJob("test")
|
||||||
|
assert.Equal(t, len(job.Steps), 3)
|
||||||
|
},
|
||||||
|
want1: "test",
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid yaml",
|
||||||
|
args: args{
|
||||||
|
task: &runnerv1.Task{
|
||||||
|
WorkflowPayload: []byte(`
|
||||||
|
name: Bad workflow
|
||||||
|
on: push
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- run: echo "ok"
|
||||||
|
bad-indent: true
|
||||||
|
`),
|
||||||
|
Needs: map[string]*runnerv1.TaskNeed{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
assert: nil,
|
||||||
|
want1: "",
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
got, got1, err := generateWorkflow(tt.args.task)
|
got, got1, err := generateWorkflow(tt.args.task)
|
||||||
|
if tt.wantErr {
|
||||||
|
require.Error(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
tt.assert(t, got)
|
tt.assert(t, got)
|
||||||
assert.Equal(t, got1, tt.want1)
|
assert.Equal(t, got1, tt.want1)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_yamlV4NodeRoundTrip(t *testing.T) {
|
||||||
|
t.Run("marshal sequence node", func(t *testing.T) {
|
||||||
|
node := yaml.Node{
|
||||||
|
Kind: yaml.SequenceNode,
|
||||||
|
Content: []*yaml.Node{
|
||||||
|
{Kind: yaml.ScalarNode, Value: "a"},
|
||||||
|
{Kind: yaml.ScalarNode, Value: "b"},
|
||||||
|
{Kind: yaml.ScalarNode, Value: "c"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
out, err := yaml.Marshal(&node)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, string(out), "- a\n- b\n- c\n")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("unmarshal and re-marshal workflow", func(t *testing.T) {
|
||||||
|
input := []byte("name: test\non: push\njobs:\n build:\n runs-on: ubuntu-latest\n steps:\n - run: echo hello\n")
|
||||||
|
|
||||||
|
var wf map[string]interface{}
|
||||||
|
err := yaml.Unmarshal(input, &wf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, wf["name"], "test")
|
||||||
|
|
||||||
|
out, err := yaml.Marshal(wf)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
var wf2 map[string]interface{}
|
||||||
|
err = yaml.Unmarshal(out, &wf2)
|
||||||
|
require.NoError(t, err)
|
||||||
|
assert.Equal(t, wf2["name"], "test")
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("node kind constants", func(t *testing.T) {
|
||||||
|
// Verify yaml/v4 node kind constants are usable (same API as v3)
|
||||||
|
require.NotEqual(t, yaml.ScalarNode, yaml.SequenceNode)
|
||||||
|
require.NotEqual(t, yaml.SequenceNode, yaml.MappingNode)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user