summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsillyguodong <33891828+sillyguodong@users.noreply.github.com>2024-03-08 07:14:35 +0100
committerEarl Warren <contact@earl-warren.org>2024-03-11 17:36:59 +0100
commit6cb9e8d86901cf475cf41f601efce9baa5df4155 (patch)
tree2c2cbde4f07a70ec5353755678bdc4343cf08ed8
parentFilter for default-branch selection (#29388) (diff)
downloadforgejo-6cb9e8d86901cf475cf41f601efce9baa5df4155.tar.xz
forgejo-6cb9e8d86901cf475cf41f601efce9baa5df4155.zip
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. (cherry picked from commit a1f5dd767729e30d07ab42fda80c19f30a72679f)
-rw-r--r--go.mod2
-rw-r--r--go.sum4
-rw-r--r--models/actions/variable.go33
-rw-r--r--models/secret/secret.go39
-rw-r--r--routers/api/actions/runner/utils.go80
-rw-r--r--services/actions/notifier_helper.go13
6 files changed, 99 insertions, 72 deletions
diff --git a/go.mod b/go.mod
index 32fdca26fe..837b233171 100644
--- a/go.mod
+++ b/go.mod
@@ -299,7 +299,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
diff --git a/go.sum b/go.sum
index 6788280b12..5f7c04bb0e 100644
--- a/go.sum
+++ b/go.sum
@@ -52,8 +52,8 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
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=
diff --git a/models/actions/variable.go b/models/actions/variable.go
index 12717e0ae4..14ded60fac 100644
--- a/models/actions/variable.go
+++ b/models/actions/variable.go
@@ -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
+}
diff --git a/models/secret/secret.go b/models/secret/secret.go
index 41e860d7f6..35bed500b9 100644
--- a/models/secret/secret.go
+++ b/models/secret/secret.go
@@ -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
+}
diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go
index a7cb31288c..ff6ec5bd54 100644
--- a/routers/api/actions/runner/utils.go
+++ b/routers/api/actions/runner/utils.go
@@ -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)
diff --git a/services/actions/notifier_helper.go b/services/actions/notifier_helper.go
index 19a5c66b71..6f0e8058a0 100644
--- a/services/actions/notifier_helper.go
+++ b/services/actions/notifier_helper.go
@@ -305,7 +305,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