diff --git a/executor.go b/executor.go index 734adf5..b250ef7 100644 --- a/executor.go +++ b/executor.go @@ -266,6 +266,8 @@ func (e *Executor) runRole(ctx context.Context, hosts []string, roleRef *RoleRef // Execute tasks for _, task := range tasks { + task := task + task.Tags = append(append([]string{}, roleRef.Tags...), task.Tags...) if err := e.runTaskOnHosts(ctx, hosts, &task, play); err != nil { // Restore vars e.vars = oldVars @@ -281,7 +283,8 @@ func (e *Executor) runRole(ctx context.Context, hosts []string, roleRef *RoleRef // runTaskOnHosts runs a task on all hosts. func (e *Executor) runTaskOnHosts(ctx context.Context, hosts []string, task *Task, play *Play) error { // Check tags - if !e.matchesTags(task.Tags) { + tags := append(append([]string{}, play.Tags...), task.Tags...) + if !e.matchesTags(tags) { return nil } diff --git a/executor_test.go b/executor_test.go index 2d79235..b94fcc1 100644 --- a/executor_test.go +++ b/executor_test.go @@ -138,6 +138,37 @@ func TestExecutor_RunPlay_Good_SerialBatchesHosts(t *testing.T) { }, gathered) } +func TestExecutor_RunPlay_Good_PlayTagsApplyToUntaggedTasks(t *testing.T) { + e := NewExecutor("/tmp") + e.SetInventoryDirect(&Inventory{ + All: &InventoryGroup{ + Hosts: map[string]*Host{ + "host1": {}, + }, + }, + }) + e.Tags = []string{"deploy"} + + var executed []string + e.OnTaskStart = func(host string, task *Task) { + executed = append(executed, host+":"+task.Name) + } + + gatherFacts := false + play := &Play{ + Name: "tagged play", + Hosts: "all", + GatherFacts: &gatherFacts, + Tags: []string{"deploy"}, + Tasks: []Task{ + {Name: "untagged task", Module: "debug", Args: map[string]any{"msg": "ok"}}, + }, + } + + require.NoError(t, e.runPlay(context.Background(), play)) + assert.Equal(t, []string{"host1:untagged task"}, executed) +} + func TestExecutor_RunTaskOnHost_Good_LoopControlPause(t *testing.T) { e := NewExecutor("/tmp") task := &Task{