(ctx context.Context, req *runtimev1.PushEnvRequest)
| 14 | ) |
| 15 | |
| 16 | func (s *Server) PushEnv(ctx context.Context, req *runtimev1.PushEnvRequest) (*runtimev1.PushEnvResponse, error) { |
| 17 | if !auth.GetClaims(ctx, req.InstanceId).Can(runtime.EditRepo) { |
| 18 | return nil, ErrForbidden |
| 19 | } |
| 20 | |
| 21 | inst, err := s.runtime.Instance(ctx, req.InstanceId) |
| 22 | if err != nil { |
| 23 | return nil, err |
| 24 | } |
| 25 | |
| 26 | repo, release, err := s.runtime.Repo(ctx, req.InstanceId) |
| 27 | if err != nil { |
| 28 | return nil, err |
| 29 | } |
| 30 | defer release() |
| 31 | |
| 32 | admin, release, err := s.runtime.Admin(ctx, req.InstanceId) |
| 33 | if err != nil { |
| 34 | return nil, err |
| 35 | } |
| 36 | defer release() |
| 37 | |
| 38 | // Parse local .env files |
| 39 | p, err := parser.Parse(ctx, repo, req.InstanceId, inst.Environment, inst.OLAPConnector, false) |
| 40 | if err != nil { |
| 41 | return nil, fmt.Errorf("failed to parse project: %w", err) |
| 42 | } |
| 43 | |
| 44 | localPerEnv := p.GetDotEnvPerEnvironment() |
| 45 | |
| 46 | // Fetch existing cloud variables |
| 47 | cfg, err := admin.GetConfig(ctx) |
| 48 | if err != nil && !errors.Is(err, drivers.ErrNotAuthenticated) { |
| 49 | return nil, fmt.Errorf("failed to get project variables: %w", err) |
| 50 | } |
| 51 | var cloudPerEnv map[string]map[string]string |
| 52 | if cfg != nil { |
| 53 | cloudPerEnv = cfg.Variables |
| 54 | } |
| 55 | if cloudPerEnv == nil { |
| 56 | cloudPerEnv = make(map[string]map[string]string) |
| 57 | } |
| 58 | |
| 59 | var addedCount, changedCount int32 |
| 60 | |
| 61 | for env, local := range localPerEnv { |
| 62 | if env != "" && env != inst.Environment { |
| 63 | // only allow pushing base variables or variables for the current environment |
| 64 | continue |
| 65 | } |
| 66 | cloud := cloudPerEnv[env] |
| 67 | |
| 68 | // Merge: start with cloud, overlay local; track what changed |
| 69 | merged := make(map[string]string) |
| 70 | maps.Copy(merged, cloud) |
| 71 | var added, changed int32 |
| 72 | for k, v := range local { |
| 73 | if _, exists := cloud[k]; !exists { |
nothing calls this directly
no test coverage detected