mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-26 12:27:06 +00:00 
			
		
		
		
	Make runs-on support variable expression (#29468)
As title. Close issue: https://gitea.com/gitea/act_runner/issues/445 Follow: https://gitea.com/gitea/act/pulls/91 Move `getSecretsOfTask` and `getVariablesOfTask` under `models` because of circular dependency issues.
This commit is contained in:
		
							
								
								
									
										2
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								go.mod
									
									
									
									
									
								
							| @@ -302,7 +302,7 @@ replace github.com/hashicorp/go-version => github.com/6543/go-version v1.3.1 | ||||
|  | ||||
| replace github.com/shurcooL/vfsgen => github.com/lunny/vfsgen v0.0.0-20220105142115-2c99e1ffdfa0 | ||||
|  | ||||
| replace github.com/nektos/act => gitea.com/gitea/act v0.2.51 | ||||
| replace github.com/nektos/act => gitea.com/gitea/act v0.259.1 | ||||
|  | ||||
| replace github.com/gorilla/feeds => github.com/yardenshoham/feeds v0.0.0-20240110072658-f3d0c21c0bd5 | ||||
|  | ||||
|   | ||||
							
								
								
									
										4
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								go.sum
									
									
									
									
									
								
							| @@ -48,8 +48,8 @@ dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= | ||||
| dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= | ||||
| git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078 h1:cliQ4HHsCo6xi2oWZYKWW4bly/Ory9FuTpFPRxj/mAg= | ||||
| git.sr.ht/~mariusor/go-xsd-duration v0.0.0-20220703122237-02e73435a078/go.mod h1:g/V2Hjas6Z1UHUp4yIx6bATpNzJ7DYtD0FG3+xARWxs= | ||||
| gitea.com/gitea/act v0.2.51 h1:gXc/B4OlTciTTzAx9cmNyw04n2SDO7exPjAsR5Idu+c= | ||||
| gitea.com/gitea/act v0.2.51/go.mod h1:CoaX2053jqBlD6JMgu4d4UgFL/rp2I14Kt5mMqcs0Z0= | ||||
| gitea.com/gitea/act v0.259.1 h1:8GG1o/xtUHl3qjn5f0h/2FXrT5ubBn05TJOM5ry+FBw= | ||||
| gitea.com/gitea/act v0.259.1/go.mod h1:UxZWRYqQG2Yj4+4OqfGWW5a3HELwejyWFQyU7F1jUD8= | ||||
| gitea.com/go-chi/binding v0.0.0-20230415142243-04b515c6d669 h1:RUBX+MK/TsDxpHmymaOaydfigEbbzqUnG1OTZU/HAeo= | ||||
| gitea.com/go-chi/binding v0.0.0-20230415142243-04b515c6d669/go.mod h1:77TZu701zMXWJFvB8gvTbQ92zQ3DQq/H7l5wAEjQRKc= | ||||
| gitea.com/go-chi/cache v0.0.0-20210110083709-82c4c9ce2d5e/go.mod h1:k2V/gPDEtXGjjMGuBJiapffAXTv76H4snSmlJRLUhH0= | ||||
|   | ||||
| @@ -10,6 +10,7 @@ import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| 	"code.gitea.io/gitea/modules/util" | ||||
|  | ||||
| @@ -82,3 +83,35 @@ func UpdateVariable(ctx context.Context, variable *ActionVariable) (bool, error) | ||||
| 		}) | ||||
| 	return count != 0, err | ||||
| } | ||||
|  | ||||
| func GetVariablesOfRun(ctx context.Context, run *ActionRun) (map[string]string, error) { | ||||
| 	variables := map[string]string{} | ||||
|  | ||||
| 	// Global | ||||
| 	globalVariables, err := db.Find[ActionVariable](ctx, FindVariablesOpts{}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find global variables: %v", err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Org / User level | ||||
| 	ownerVariables, err := db.Find[ActionVariable](ctx, FindVariablesOpts{OwnerID: run.Repo.OwnerID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find variables of org: %d, error: %v", run.Repo.OwnerID, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Repo level | ||||
| 	repoVariables, err := db.Find[ActionVariable](ctx, FindVariablesOpts{RepoID: run.RepoID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find variables of repo: %d, error: %v", run.RepoID, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Level precedence: Repo > Org / User > Global | ||||
| 	for _, v := range append(globalVariables, append(ownerVariables, repoVariables...)...) { | ||||
| 		variables[v.Name] = v.Data | ||||
| 	} | ||||
|  | ||||
| 	return variables, nil | ||||
| } | ||||
|   | ||||
| @@ -9,7 +9,10 @@ import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
|  | ||||
| 	actions_model "code.gitea.io/gitea/models/actions" | ||||
| 	"code.gitea.io/gitea/models/db" | ||||
| 	actions_module "code.gitea.io/gitea/modules/actions" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	secret_module "code.gitea.io/gitea/modules/secret" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/modules/timeutil" | ||||
| @@ -112,3 +115,39 @@ func UpdateSecret(ctx context.Context, secretID int64, data string) error { | ||||
| 	} | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[string]string, error) { | ||||
| 	secrets := map[string]string{} | ||||
|  | ||||
| 	secrets["GITHUB_TOKEN"] = task.Token | ||||
| 	secrets["GITEA_TOKEN"] = task.Token | ||||
|  | ||||
| 	if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { | ||||
| 		// ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated. | ||||
| 		// for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch | ||||
| 		// see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target | ||||
| 		return secrets, nil | ||||
| 	} | ||||
|  | ||||
| 	ownerSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{OwnerID: task.Job.Run.Repo.OwnerID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find secrets of owner %v: %v", task.Job.Run.Repo.OwnerID, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	repoSecrets, err := db.Find[Secret](ctx, FindSecretsOptions{RepoID: task.Job.Run.RepoID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find secrets of repo %v: %v", task.Job.Run.RepoID, err) | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	for _, secret := range append(ownerSecrets, repoSecrets...) { | ||||
| 		v, err := secret_module.DecryptSecret(setting.SecretKey, secret.Data) | ||||
| 		if err != nil { | ||||
| 			log.Error("decrypt secret %v %q: %v", secret.ID, secret.Name, err) | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		secrets[secret.Name] = v | ||||
| 	} | ||||
|  | ||||
| 	return secrets, nil | ||||
| } | ||||
|   | ||||
| @@ -15,7 +15,6 @@ import ( | ||||
| 	"code.gitea.io/gitea/modules/git" | ||||
| 	"code.gitea.io/gitea/modules/json" | ||||
| 	"code.gitea.io/gitea/modules/log" | ||||
| 	secret_module "code.gitea.io/gitea/modules/secret" | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 	"code.gitea.io/gitea/services/actions" | ||||
|  | ||||
| @@ -32,14 +31,24 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv | ||||
| 		return nil, false, nil | ||||
| 	} | ||||
|  | ||||
| 	secrets, err := secret_model.GetSecretsOfTask(ctx, t) | ||||
| 	if err != nil { | ||||
| 		return nil, false, fmt.Errorf("GetSecretsOfTask: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	vars, err := actions_model.GetVariablesOfRun(ctx, t.Job.Run) | ||||
| 	if err != nil { | ||||
| 		return nil, false, fmt.Errorf("GetVariablesOfRun: %w", err) | ||||
| 	} | ||||
|  | ||||
| 	actions.CreateCommitStatus(ctx, t.Job) | ||||
|  | ||||
| 	task := &runnerv1.Task{ | ||||
| 		Id:              t.ID, | ||||
| 		WorkflowPayload: t.Job.WorkflowPayload, | ||||
| 		Context:         generateTaskContext(t), | ||||
| 		Secrets:         getSecretsOfTask(ctx, t), | ||||
| 		Vars:            getVariablesOfTask(ctx, t), | ||||
| 		Secrets:         secrets, | ||||
| 		Vars:            vars, | ||||
| 	} | ||||
|  | ||||
| 	if needs, err := findTaskNeeds(ctx, t); err != nil { | ||||
| @@ -55,71 +64,6 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv | ||||
| 	return task, true, nil | ||||
| } | ||||
|  | ||||
| func getSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { | ||||
| 	secrets := map[string]string{} | ||||
|  | ||||
| 	secrets["GITHUB_TOKEN"] = task.Token | ||||
| 	secrets["GITEA_TOKEN"] = task.Token | ||||
|  | ||||
| 	if task.Job.Run.IsForkPullRequest && task.Job.Run.TriggerEvent != actions_module.GithubEventPullRequestTarget { | ||||
| 		// ignore secrets for fork pull request, except GITHUB_TOKEN and GITEA_TOKEN which are automatically generated. | ||||
| 		// for the tasks triggered by pull_request_target event, they could access the secrets because they will run in the context of the base branch | ||||
| 		// see the documentation: https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request_target | ||||
| 		return secrets | ||||
| 	} | ||||
|  | ||||
| 	ownerSecrets, err := db.Find[secret_model.Secret](ctx, secret_model.FindSecretsOptions{OwnerID: task.Job.Run.Repo.OwnerID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find secrets of owner %v: %v", task.Job.Run.Repo.OwnerID, err) | ||||
| 		// go on | ||||
| 	} | ||||
| 	repoSecrets, err := db.Find[secret_model.Secret](ctx, secret_model.FindSecretsOptions{RepoID: task.Job.Run.RepoID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find secrets of repo %v: %v", task.Job.Run.RepoID, err) | ||||
| 		// go on | ||||
| 	} | ||||
|  | ||||
| 	for _, secret := range append(ownerSecrets, repoSecrets...) { | ||||
| 		if v, err := secret_module.DecryptSecret(setting.SecretKey, secret.Data); err != nil { | ||||
| 			log.Error("decrypt secret %v %q: %v", secret.ID, secret.Name, err) | ||||
| 			// go on | ||||
| 		} else { | ||||
| 			secrets[secret.Name] = v | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return secrets | ||||
| } | ||||
|  | ||||
| func getVariablesOfTask(ctx context.Context, task *actions_model.ActionTask) map[string]string { | ||||
| 	variables := map[string]string{} | ||||
|  | ||||
| 	// Global | ||||
| 	globalVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find global variables: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Org / User level | ||||
| 	ownerVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{OwnerID: task.Job.Run.Repo.OwnerID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find variables of org: %d, error: %v", task.Job.Run.Repo.OwnerID, err) | ||||
| 	} | ||||
|  | ||||
| 	// Repo level | ||||
| 	repoVariables, err := db.Find[actions_model.ActionVariable](ctx, actions_model.FindVariablesOpts{RepoID: task.Job.Run.RepoID}) | ||||
| 	if err != nil { | ||||
| 		log.Error("find variables of repo: %d, error: %v", task.Job.Run.RepoID, err) | ||||
| 	} | ||||
|  | ||||
| 	// Level precedence: Repo > Org / User > Global | ||||
| 	for _, v := range append(globalVariables, append(ownerVariables, repoVariables...)...) { | ||||
| 		variables[v.Name] = v.Data | ||||
| 	} | ||||
|  | ||||
| 	return variables | ||||
| } | ||||
|  | ||||
| func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { | ||||
| 	event := map[string]any{} | ||||
| 	_ = json.Unmarshal([]byte(t.Job.Run.EventPayload), &event) | ||||
|   | ||||
| @@ -296,7 +296,18 @@ func handleWorkflows( | ||||
| 			run.NeedApproval = need | ||||
| 		} | ||||
|  | ||||
| 		jobs, err := jobparser.Parse(dwf.Content) | ||||
| 		if err := run.LoadAttributes(ctx); err != nil { | ||||
| 			log.Error("LoadAttributes: %v", err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		vars, err := actions_model.GetVariablesOfRun(ctx, run) | ||||
| 		if err != nil { | ||||
| 			log.Error("GetVariablesOfRun: %v", err) | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		jobs, err := jobparser.Parse(dwf.Content, jobparser.WithVars(vars)) | ||||
| 		if err != nil { | ||||
| 			log.Error("jobparser.Parse: %v", err) | ||||
| 			continue | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 sillyguodong
					sillyguodong