···147147make
148148```
149149150150+## TODOs
151151+152152+- Fix OCI plain HTTP for local development
153153+- Remove hardcoded git username and email
154154+- Credentials for the worker (SSH priv + pub + knowhosts?)
155155+150156## Acknowledgments and References
151157152158- [Oracle Terraform Modules](https://github.com/oracle-terraform-modules)
+79
controller/activities/app.go
···1111 "strings"
12121313 "go.temporal.io/sdk/activity"
1414+ "gopkg.in/yaml.v3"
1415)
15161617func PushRenderedApp(ctx context.Context, appsPath, namespace, app, cluster, registry string) (*PushResult, error) {
···8384 }
8485 return matched, nil
8586}
8787+8888+type Image struct {
8989+ Repository string
9090+ Tag string
9191+}
9292+9393+func updateImageTags(node *yaml.Node, newImages []Image) error {
9494+ var walk func(n *yaml.Node)
9595+ walk = func(n *yaml.Node) {
9696+ if n.Kind != yaml.MappingNode {
9797+ for _, child := range n.Content {
9898+ walk(child)
9999+ }
100100+ return
101101+ }
102102+ for i := 0; i < len(n.Content)-1; i += 2 {
103103+ key := n.Content[i]
104104+ val := n.Content[i+1]
105105+ if key.Value == "image" && val.Kind == yaml.MappingNode {
106106+ var repoNode, tagNode *yaml.Node
107107+ for j := 0; j < len(val.Content)-1; j += 2 {
108108+ k := val.Content[j]
109109+ v := val.Content[j+1]
110110+ switch k.Value {
111111+ case "repository":
112112+ repoNode = v
113113+ case "tag":
114114+ tagNode = v
115115+ }
116116+ }
117117+ if repoNode != nil && tagNode != nil {
118118+ for _, img := range newImages {
119119+ if repoNode.Value == img.Repository {
120120+ tagNode.Value = img.Tag
121121+ }
122122+ }
123123+ }
124124+ } else {
125125+ walk(val)
126126+ }
127127+ }
128128+ }
129129+ walk(node)
130130+ return nil
131131+}
132132+133133+func UpdateAppVersion(ctx context.Context, appsDir, namespace, app, cluster string, newImages []Image) error {
134134+ path := filepath.Join(appsDir, namespace, app, fmt.Sprintf("%s.yaml", cluster))
135135+136136+ data, err := os.ReadFile(path)
137137+ if err != nil {
138138+ return fmt.Errorf("failed to read file: %w", err)
139139+ }
140140+141141+ var node yaml.Node
142142+ if err := yaml.Unmarshal(data, &node); err != nil {
143143+ return fmt.Errorf("failed to unmarshal YAML: %w", err)
144144+ }
145145+146146+ if err := updateImageTags(&node, newImages); err != nil {
147147+ return fmt.Errorf("failed to update image tags: %w", err)
148148+ }
149149+150150+ var buf bytes.Buffer
151151+ encoder := yaml.NewEncoder(&buf)
152152+ encoder.SetIndent(2)
153153+154154+ if err := encoder.Encode(&node); err != nil {
155155+ return fmt.Errorf("failed to encode YAML: %w", err)
156156+ }
157157+ encoder.Close()
158158+159159+ if err := os.WriteFile(path, buf.Bytes(), 0644); err != nil {
160160+ return fmt.Errorf("failed to write YAML file: %w", err)
161161+ }
162162+163163+ return nil
164164+}