<commit_before>package main

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"os"
	"path"
	"strings"
	"time"

	"github.com/ovh/cds/engine/api/worker"
	"github.com/ovh/cds/sdk"
	"github.com/ovh/cds/sdk/cdsclient"
	"github.com/ovh/cds/sdk/interpolate"
	"github.com/ovh/cds/sdk/log"
	"github.com/ovh/cds/sdk/vcs"
)

func processJobParameter(params *[]sdk.Parameter, secrets []sdk.Variable) {
	parameters := *params

	for i := range parameters {
		keepReplacing := true
		for keepReplacing {
			t := parameters[i].Value

			for _, p := range parameters {
				parameters[i].Value = strings.Replace(parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			for _, p := range secrets {
				parameters[i].Value = strings.Replace(parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			// If parameters wasn't updated, consider it done
			if parameters[i].Value == t {
				keepReplacing = false
			}
		}
	}

	params = &parameters
	return
}

// ProcessActionVariables replaces all placeholders inside action recursively using
// - parent parameters
// - action build arguments
// - Secrets from project, application and environment
//
// This function should be called ONLY from worker
func (w *currentWorker) processActionVariables(a *sdk.Action, parent *sdk.Action, jobParameters []sdk.Parameter, secrets []sdk.Variable) error {
	// replaces placeholder in parameters with ActionBuild variables
	// replaces placeholder in parameters with Parent params
	for i := range a.Parameters {
		keepReplacing := true
		for keepReplacing {
			t := a.Parameters[i].Value

			if parent != nil {
				for _, p := range parent.Parameters {
					a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
				}
			}

			for _, p := range jobParameters {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			for _, p := range secrets {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			// If parameters wasn't updated, consider it done
			if a.Parameters[i].Value == t {
				keepReplacing = false
			}
		}
	}

	// replaces placeholder in all children recursively
	for i := range a.Actions {
		if err := w.processActionVariables(&a.Actions[i], a, jobParameters, secrets); err != nil {
			return nil
		}
	}

	return nil
}

func (w *currentWorker) startAction(ctx context.Context, a *sdk.Action, buildID int64, params *[]sdk.Parameter, secrets []sdk.Variable, stepOrder int, stepName string) sdk.Result {
	// Process action build arguments
	for _, abp := range *params {
		// Process build variable for root action
		for j := range a.Parameters {
			if abp.Name == a.Parameters[j].Name {
				a.Parameters[j].Value = abp.Value
			}
		}
	}

	if a.Name != sdk.ScriptAction {
		// ExpandEnv over all action parameters, avoid expending "CDS_*" env variables
		var getFilteredEnv = func(s string) string {
			if strings.HasPrefix(s, "CDS_") {
				return s
			}
			return os.Getenv(s)
		}
		for i := range a.Parameters {
			a.Parameters[i].Value = os.Expand(a.Parameters[i].Value, getFilteredEnv)
		}
	}

	return w.runJob(ctx, a, buildID, params, secrets, stepOrder, stepName)
}

func (w *currentWorker) replaceVariablesPlaceholder(a *sdk.Action, params []sdk.Parameter) error {
	if w.currentJob.wJob != nil { // cds workflow, use helper from interpolate
		tmp := map[string]string{}
		for _, v := range w.currentJob.buildVariables {
			tmp[v.Name] = v.Value
		}
		for _, v := range params {
			tmp[v.Name] = v.Value
		}

		for i := range a.Parameters {
			var err error
			a.Parameters[i].Value, err = interpolate.Do(a.Parameters[i].Value, tmp)
			if err != nil {
				return sdk.WrapError(err, "Unable to interpolate action parameters")
			}
		}
	} else { // pipeline build Job
		for i := range a.Parameters {
			for _, v := range w.currentJob.buildVariables {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+v.Name+"}}", v.Value, -1)
			}
			for _, v := range params {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+v.Name+"}}", v.Value, -1)
			}
		}
	}
	return nil
}

func (w *currentWorker) runJob(ctx context.Context, a *sdk.Action, buildID int64, params *[]sdk.Parameter, secrets []sdk.Variable, stepOrder int, stepName string) sdk.Result {
	log.Info("runJob> start run %d stepOrder:%d", buildID, stepOrder)
	defer func() { log.Info("runJob> end run %d stepOrder:%d", buildID, stepOrder) }()
	// Replace variable placeholder that may have been added by last step
	if err := w.replaceVariablesPlaceholder(a, *params); err != nil {
		return sdk.Result{
			Status:  sdk.StatusFail.String(),
			BuildID: buildID,
			Reason:  "Unable to interpolate action parameters",
		}
	}
	// Set the params
	w.currentJob.params = *params
	// Unset the params at the end
	defer func() {
		w.currentJob.params = nil
	}()

	//If the action is disabled; skip it
	if !a.Enabled {
		return sdk.Result{
			Status:  sdk.StatusDisabled.String(),
			BuildID: buildID,
		}
	}

	//If the action if a edge of the action tree; run it
	switch a.Type {
	case sdk.BuiltinAction:
		return w.runBuiltin(ctx, a, buildID, params, secrets, stepOrder)
	case sdk.PluginAction:
		//Define a loggin function
		sendLog := getLogger(w, buildID, stepOrder)
		//Run the plugin<commit_msg>fix(worker): add error line number #3068 (#3069)<commit_after>package main

import (
	"context"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"os"
	"path"
	"strings"
	"time"

	"github.com/ovh/cds/engine/api/worker"
	"github.com/ovh/cds/sdk"
	"github.com/ovh/cds/sdk/cdsclient"
	"github.com/ovh/cds/sdk/interpolate"
	"github.com/ovh/cds/sdk/log"
	"github.com/ovh/cds/sdk/vcs"
)

func processJobParameter(params *[]sdk.Parameter, secrets []sdk.Variable) {
	parameters := *params

	for i := range parameters {
		keepReplacing := true
		for keepReplacing {
			t := parameters[i].Value

			for _, p := range parameters {
				parameters[i].Value = strings.Replace(parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			for _, p := range secrets {
				parameters[i].Value = strings.Replace(parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			// If parameters wasn't updated, consider it done
			if parameters[i].Value == t {
				keepReplacing = false
			}
		}
	}

	params = &parameters
	return
}

// ProcessActionVariables replaces all placeholders inside action recursively using
// - parent parameters
// - action build arguments
// - Secrets from project, application and environment
//
// This function should be called ONLY from worker
func (w *currentWorker) processActionVariables(a *sdk.Action, parent *sdk.Action, jobParameters []sdk.Parameter, secrets []sdk.Variable) error {
	// replaces placeholder in parameters with ActionBuild variables
	// replaces placeholder in parameters with Parent params
	for i := range a.Parameters {
		keepReplacing := true
		for keepReplacing {
			t := a.Parameters[i].Value

			if parent != nil {
				for _, p := range parent.Parameters {
					a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
				}
			}

			for _, p := range jobParameters {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			for _, p := range secrets {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+p.Name+"}}", p.Value, -1)
			}

			// If parameters wasn't updated, consider it done
			if a.Parameters[i].Value == t {
				keepReplacing = false
			}
		}
	}

	// replaces placeholder in all children recursively
	for i := range a.Actions {
		if err := w.processActionVariables(&a.Actions[i], a, jobParameters, secrets); err != nil {
			return nil
		}
	}

	return nil
}

func (w *currentWorker) startAction(ctx context.Context, a *sdk.Action, buildID int64, params *[]sdk.Parameter, secrets []sdk.Variable, stepOrder int, stepName string) sdk.Result {
	// Process action build arguments
	for _, abp := range *params {
		// Process build variable for root action
		for j := range a.Parameters {
			if abp.Name == a.Parameters[j].Name {
				a.Parameters[j].Value = abp.Value
			}
		}
	}

	if a.Name != sdk.ScriptAction {
		// ExpandEnv over all action parameters, avoid expending "CDS_*" env variables
		var getFilteredEnv = func(s string) string {
			if strings.HasPrefix(s, "CDS_") {
				return s
			}
			return os.Getenv(s)
		}
		for i := range a.Parameters {
			a.Parameters[i].Value = os.Expand(a.Parameters[i].Value, getFilteredEnv)
		}
	}

	return w.runJob(ctx, a, buildID, params, secrets, stepOrder, stepName)
}

func (w *currentWorker) replaceVariablesPlaceholder(a *sdk.Action, params []sdk.Parameter) error {
	if w.currentJob.wJob != nil { // cds workflow, use helper from interpolate
		tmp := map[string]string{}
		for _, v := range w.currentJob.buildVariables {
			tmp[v.Name] = v.Value
		}
		for _, v := range params {
			tmp[v.Name] = v.Value
		}

		for i := range a.Parameters {
			var err error
			a.Parameters[i].Value, err = interpolate.Do(a.Parameters[i].Value, tmp)
			if err != nil {
				return sdk.WrapError(err, "Unable to interpolate action parameters")
			}
		}
	} else { // pipeline build Job
		for i := range a.Parameters {
			for _, v := range w.currentJob.buildVariables {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+v.Name+"}}", v.Value, -1)
			}
			for _, v := range params {
				a.Parameters[i].Value = strings.Replace(a.Parameters[i].Value, "{{."+v.Name+"}}", v.Value, -1)
			}
		}
	}
	return nil
}

func (w *currentWorker) runJob(ctx context.Context, a *sdk.Action, buildID int64, params *[]sdk.Parameter, secrets []sdk.Variable, stepOrder int, stepName string) sdk.Result {
	log.Info("runJob> start run %d stepOrder:%d", buildID, stepOrder)
	defer func() { log.Info("runJob> end run %d stepOrder:%d", buildID, stepOrder) }()
	// Replace variable placeholder that may have been added by last step
	if err := w.replaceVariablesPlaceholder(a, *params); err != nil {
		return sdk.Result{
			Status:  sdk.StatusFail.String(),
			BuildID: buildID,
			Reason:  err.Error(),
		}
	}
	// Set the params
	w.currentJob.params = *params
	// Unset the params at the end
	defer func() {
		w.currentJob.params = nil
	}()

	//If the action is disabled; skip it
	if !a.Enabled {
		return sdk.Result{
			Status:  sdk.StatusDisabled.String(),
			BuildID: buildID,
		}
	}

	//If the action if a edge of the action tree; run it
	switch a.Type {
	case sdk.BuiltinAction:
		return w.runBuiltin(ctx, a, buildID, params, secrets, stepOrder)
	case sdk.PluginAction:
		//Define a loggin function
		sendLog := getLogger(w, buildID, stepOrder)
		//Run the plugin
{'fraction_non_alphanumeric': 0.146752881641833, 'fraction_numerical': 0.0028113578858588698, 'mean_word_length': 3.4466666666666668, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '768409', 'n_tokens_mistral': 3977, 'n_tokens_neox': 3573, 'n_words': 969}