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:
@@ -11,7 +11,7 @@ import (
|
||||
|
||||
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
||||
"github.com/nektos/act/pkg/model"
|
||||
"gopkg.in/yaml.v3"
|
||||
"go.yaml.in/yaml/v4"
|
||||
)
|
||||
|
||||
func generateWorkflow(task *runnerv1.Task) (*model.Workflow, string, error) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
|
||||
"github.com/nektos/act/pkg/model"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.yaml.in/yaml/v4"
|
||||
"gotest.tools/v3/assert"
|
||||
)
|
||||
|
||||
@@ -62,13 +63,267 @@ jobs:
|
||||
want1: "job9",
|
||||
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 {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, got1, err := generateWorkflow(tt.args.task)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
require.NoError(t, err)
|
||||
tt.assert(t, got)
|
||||
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