We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[Bug]: Cron created by manifest workflow doesn't have build_platform parameter
### Describe the bug

Our manifest workflow will help us create input manifest and add the build job to our cron once we have a new version from OS or OSD core. e.g. #2894 

However since we start to build for different platform distribution, we would need to add build_platform parameters to trigger the build workflow which our current manifest workflow doesn't have. We would need to manually add the param to the cron in order to trigger it. #2911 

### To reproduce

When we have a new OS or OSD version, run `./manifest.sh update`

### Expected behavior

When the workflow raise the PR, it should also add this param to the cron. For different job type(OS or OSD), it would also add different platform parameter. e.g. for OS it should be `BUILD_PLATFORM=linux macos windows` but for OSD it's `BUILD_PLATFORM=linux windows`

### Screenshots

If applicable, add screenshots to help explain your problem.

### Host / Environment

_No response_

### Additional context

_No response_

### Relevant log output

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/manifests_workflow/input_manifests.py`
Content:
```
1 # Copyright OpenSearch Contributors
2 # SPDX-License-Identifier: Apache-2.0
3 #
4 # The OpenSearch Contributors require contributions made to
5 # this file be licensed under the Apache-2.0 license or a
6 # compatible open source license.
7 
8 import glob
9 import logging
10 import os
11 import re
12 from abc import abstractmethod
13 from typing import Dict, List, Type, Union
14 
15 import ruamel.yaml
16 
17 from manifests.component_manifest import ComponentFromSource
18 from manifests.input_manifest import InputComponents, InputManifest
19 from manifests.manifests import Manifests
20 from manifests_workflow.component_opensearch import ComponentOpenSearch
21 from manifests_workflow.component_opensearch_dashboards_min import ComponentOpenSearchDashboardsMin
22 from manifests_workflow.component_opensearch_min import ComponentOpenSearchMin
23 from system.temporary_directory import TemporaryDirectory
24 
25 
26 class InputManifests(Manifests):
27     def __init__(self, name: str) -> None:
28         self.name = name
29         self.prefix = name.lower().replace(" ", "-")
30         super().__init__(InputManifest, InputManifests.files(self.prefix))
31 
32     @classmethod
33     def manifests_path(self) -> str:
34         return os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", "manifests"))
35 
36     @classmethod
37     def workflows_path(self) -> str:
38         return os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", ".github", "workflows"))
39 
40     @classmethod
41     def legacy_manifests_path(self) -> str:
42         return os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", "legacy-manifests"))
43 
44     @classmethod
45     def jenkins_path(self) -> str:
46         return os.path.realpath(os.path.join(os.path.dirname(__file__), "..", "..", "jenkins"))
47 
48     @classmethod
49     def cron_jenkinsfile(self) -> str:
50         return os.path.join(self.jenkins_path(), "check-for-build.jenkinsfile")
51 
52     @classmethod
53     def versionincrement_workflow(self) -> str:
54         return os.path.join(self.workflows_path(), "increment-plugin-versions.yml")
55 
56     @classmethod
57     def files(self, name: str) -> List:
58         results = []
59         for path in [self.manifests_path(), self.legacy_manifests_path()]:
60             for filename in glob.glob(os.path.join(path, f"**/{name}-*.yml")):
61                 # avoids the -maven manifest
62                 match = re.search(rf"^{name}-([0-9.]*).yml$", os.path.basename(filename))
63                 if match:
64                     results.append(filename)
65         return results
66 
67     @abstractmethod
68     def update(
69         self,
70         min_klass: Union[Type[ComponentOpenSearchMin], Type[ComponentOpenSearchDashboardsMin]],
71         component_klass: Type[ComponentOpenSearch],
72         keep: bool = False,
73     ) -> None:
74         known_versions = self.versions
75         logging.info(f"Known versions: {known_versions}")
76         main_versions: Dict = {}
77         with TemporaryDirectory(keep=keep, chdir=True) as work_dir:
78             logging.info(f"Checking out components into {work_dir.name}")
79 
80             # check out and build #main, 1.x, etc.
81             branches = min_klass.branches()
82 
83             logging.info(f"Checking {self.name} {branches} branches")
84             for branch in branches:
85                 c = min_klass.checkout(
86                     path=os.path.join(work_dir.name, self.name.replace(" ", ""), branch),
87                     branch=branch,
88                 )
89 
90                 version = c.version
91                 logging.info(f"{self.name}#{branch} is version {version}")
92                 if version not in main_versions.keys():
93                     main_versions[version] = [c]
94 
95             if component_klass is not None:
96                 # components can increment their own version first without incrementing min
97                 manifest = self.latest
98                 logging.info(f"Examining components in the latest manifest of {manifest.build.name} ({manifest.build.version})")
99                 for component in manifest.components.values():
100                     if component.name == self.name:
101                         continue
102 
103                     if type(component) is ComponentFromSource:
104                         logging.info(f"Checking out {component.name}#main")
105                         component = component_klass.checkout(
106                             name=component.name,
107                             path=os.path.join(work_dir.name, component.name),
108                             opensearch_version=manifest.build.version,
109                             repo_url=component.repository,
110                             branch="main",
111                         )
112 
113                         component_version = component.version
114                         if component_version:
115                             release_version = ".".join(component_version.split(".")[:3])
116                             if release_version not in main_versions.keys():
117                                 main_versions[release_version] = []
118                             main_versions[release_version].append(component)
119                             logging.info(f"{component.name}#main is version {release_version} (from {component_version})")
120 
121             # summarize
122             logging.info("Found versions on main:")
123             for main_version in main_versions.keys():
124                 for component in main_versions[main_version]:
125                     logging.info(f" {component.name}={main_version}")
126 
127             # generate new manifests
128             for release_version in sorted(main_versions.keys() - known_versions):
129                 self.write_manifest(release_version, main_versions[release_version])
130                 self.add_to_cron(release_version)
131                 self.add_to_versionincrement_workflow(release_version)
132 
133     def create_manifest(self, version: str, components: List = []) -> InputManifest:
134         templates_base_path = os.path.join(self.manifests_path(), "templates")
135         template_version_folder = version.split(".")[0] + ".x"
136         template_full_path = os.path.join(templates_base_path, self.prefix, template_version_folder, "manifest.yml")
137         if not os.path.exists(template_full_path):
138             template_full_path = os.path.join(templates_base_path, self.prefix, "default", "manifest.yml")
139 
140         manifest = InputManifest.from_file(open(template_full_path))
141 
142         manifest.build.version = version
143         manifests_components = []
144 
145         for component in components:
146             logging.info(f" Adding {component.name}")
147             manifests_components.append(component.to_dict())
148 
149         manifest.components = InputComponents(manifests_components)  # type: ignore
150         return manifest
151 
152     def write_manifest(self, version: str, components: List = []) -> None:
153         logging.info(f"Creating new version: {version}")
154         manifest = self.create_manifest(version, components)
155         manifest_dir = os.path.join(self.manifests_path(), version)
156         os.makedirs(manifest_dir, exist_ok=True)
157         manifest_path = os.path.join(manifest_dir, f"{self.prefix}-{version}.yml")
158         manifest.to_file(manifest_path)
159         logging.info(f"Wrote {manifest_path}")
160 
161     def add_to_cron(self, version: str) -> None:
162         logging.info(f"Adding new version to cron: {version}")
163         jenkinsfile = self.cron_jenkinsfile()
164         with open(jenkinsfile, "r") as f:
165             data = f.read()
166 
167         cron_entry = f"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;TARGET_JOB_NAME=distribution-build-{self.prefix}\n"
168 
169         if cron_entry in data:
170             raise ValueError(f"{jenkinsfile} already contains an entry for {self.prefix} {version}")
171 
172         data = data.replace("parameterizedCron '''\n", f"parameterizedCron '''\n{' ' * 12}{cron_entry}")
173 
174         with open(jenkinsfile, "w") as f:
175             f.write(data)
176 
177         logging.info(f"Wrote {jenkinsfile}")
178 
179     def add_to_versionincrement_workflow(self, version: str) -> None:
180         versionincrement_workflow_file = self.versionincrement_workflow()
181         yaml = ruamel.yaml.YAML()
182         yaml.explicit_start = True  # type: ignore
183         yaml.preserve_quotes = True  # type: ignore
184 
185         with open(versionincrement_workflow_file) as f:
186             data = yaml.load(f)
187 
188         version_entry = []
189         major_version_entry = version.split(".")[0] + ".x"
190         minor_version_entry = version.rsplit(".", 1)[0]
191         if minor_version_entry not in data["jobs"]["plugin-version-increment-sync"]["strategy"]["matrix"]["branch"]:
192             print(f"Adding {minor_version_entry} to {versionincrement_workflow_file}")
193             version_entry.append(minor_version_entry)
194         if major_version_entry not in data["jobs"]["plugin-version-increment-sync"]["strategy"]["matrix"]["branch"]:
195             print(f"Adding {major_version_entry} to {versionincrement_workflow_file}")
196             version_entry.append(major_version_entry)
197 
198         if version_entry:
199             branch_list = list(data["jobs"]["plugin-version-increment-sync"]["strategy"]["matrix"]["branch"])
200             branch_list.extend(version_entry)
201             data["jobs"]["plugin-version-increment-sync"]["strategy"]["matrix"]["branch"] = branch_list
202             yaml.indent(mapping=2, sequence=4, offset=2)
203             with open(versionincrement_workflow_file, 'w') as f:
204                 yaml.dump(data, f)
205             logging.info("Added new version to the version increment workflow")
206
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/manifests_workflow/input_manifests.py b/src/manifests_workflow/input_manifests.py
--- a/src/manifests_workflow/input_manifests.py
+++ b/src/manifests_workflow/input_manifests.py
@@ -24,6 +24,11 @@
 
 
 class InputManifests(Manifests):
+    BUILD_PLATFORM = {
+        "opensearch": "linux macos windows",
+        "opensearch-dashboards": "linux windows"
+    }
+
     def __init__(self, name: str) -> None:
         self.name = name
         self.prefix = name.lower().replace(" ", "-")
@@ -164,7 +169,11 @@
         with open(jenkinsfile, "r") as f:
             data = f.read()
 
-        cron_entry = f"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;TARGET_JOB_NAME=distribution-build-{self.prefix}\n"
+        build_platform = self.BUILD_PLATFORM.get(self.prefix, "linux")
+
+        cron_entry = f"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;" \
+                     f"TARGET_JOB_NAME=distribution-build-{self.prefix};" \
+                     f"BUILD_PLATFORM={build_platform}\n"
 
         if cron_entry in data:
             raise ValueError(f"{jenkinsfile} already contains an entry for {self.prefix} {version}")

{"golden_diff": "diff --git a/src/manifests_workflow/input_manifests.py b/src/manifests_workflow/input_manifests.py\n--- a/src/manifests_workflow/input_manifests.py\n+++ b/src/manifests_workflow/input_manifests.py\n@@ -24,6 +24,11 @@\n \n \n class InputManifests(Manifests):\n+    BUILD_PLATFORM = {\n+        \"opensearch\": \"linux macos windows\",\n+        \"opensearch-dashboards\": \"linux windows\"\n+    }\n+\n     def __init__(self, name: str) -> None:\n         self.name = name\n         self.prefix = name.lower().replace(\" \", \"-\")\n@@ -164,7 +169,11 @@\n         with open(jenkinsfile, \"r\") as f:\n             data = f.read()\n \n-        cron_entry = f\"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;TARGET_JOB_NAME=distribution-build-{self.prefix}\\n\"\n+        build_platform = self.BUILD_PLATFORM.get(self.prefix, \"linux\")\n+\n+        cron_entry = f\"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;\" \\\n+                     f\"TARGET_JOB_NAME=distribution-build-{self.prefix};\" \\\n+                     f\"BUILD_PLATFORM={build_platform}\\n\"\n \n         if cron_entry in data:\n             raise ValueError(f\"{jenkinsfile} already contains an entry for {self.prefix} {version}\")\n", "issue": "[Bug]: Cron created by manifest workflow doesn't have build_platform parameter\n### Describe the bug\n\nOur manifest workflow will help us create input manifest and add the build job to our cron once we have a new version from OS or OSD core. e.g. #2894 \r\n\r\nHowever since we start to build for different platform distribution, we would need to add build_platform parameters to trigger the build workflow which our current manifest workflow doesn't have. We would need to manually add the param to the cron in order to trigger it. #2911 \n\n### To reproduce\n\nWhen we have a new OS or OSD version, run `./manifest.sh update`\n\n### Expected behavior\n\nWhen the workflow raise the PR, it should also add this param to the cron. For different job type(OS or OSD), it would also add different platform parameter. e.g. for OS it should be `BUILD_PLATFORM=linux macos windows` but for OSD it's `BUILD_PLATFORM=linux windows`\n\n### Screenshots\n\nIf applicable, add screenshots to help explain your problem.\n\n### Host / Environment\n\n_No response_\n\n### Additional context\n\n_No response_\n\n### Relevant log output\n\n_No response_\n", "before_files": [{"content": "# Copyright OpenSearch Contributors\n# SPDX-License-Identifier: Apache-2.0\n#\n# The OpenSearch Contributors require contributions made to\n# this file be licensed under the Apache-2.0 license or a\n# compatible open source license.\n\nimport glob\nimport logging\nimport os\nimport re\nfrom abc import abstractmethod\nfrom typing import Dict, List, Type, Union\n\nimport ruamel.yaml\n\nfrom manifests.component_manifest import ComponentFromSource\nfrom manifests.input_manifest import InputComponents, InputManifest\nfrom manifests.manifests import Manifests\nfrom manifests_workflow.component_opensearch import ComponentOpenSearch\nfrom manifests_workflow.component_opensearch_dashboards_min import ComponentOpenSearchDashboardsMin\nfrom manifests_workflow.component_opensearch_min import ComponentOpenSearchMin\nfrom system.temporary_directory import TemporaryDirectory\n\n\nclass InputManifests(Manifests):\n    def __init__(self, name: str) -> None:\n        self.name = name\n        self.prefix = name.lower().replace(\" \", \"-\")\n        super().__init__(InputManifest, InputManifests.files(self.prefix))\n\n    @classmethod\n    def manifests_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"manifests\"))\n\n    @classmethod\n    def workflows_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \".github\", \"workflows\"))\n\n    @classmethod\n    def legacy_manifests_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"legacy-manifests\"))\n\n    @classmethod\n    def jenkins_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"jenkins\"))\n\n    @classmethod\n    def cron_jenkinsfile(self) -> str:\n        return os.path.join(self.jenkins_path(), \"check-for-build.jenkinsfile\")\n\n    @classmethod\n    def versionincrement_workflow(self) -> str:\n        return os.path.join(self.workflows_path(), \"increment-plugin-versions.yml\")\n\n    @classmethod\n    def files(self, name: str) -> List:\n        results = []\n        for path in [self.manifests_path(), self.legacy_manifests_path()]:\n            for filename in glob.glob(os.path.join(path, f\"**/{name}-*.yml\")):\n                # avoids the -maven manifest\n                match = re.search(rf\"^{name}-([0-9.]*).yml$\", os.path.basename(filename))\n                if match:\n                    results.append(filename)\n        return results\n\n    @abstractmethod\n    def update(\n        self,\n        min_klass: Union[Type[ComponentOpenSearchMin], Type[ComponentOpenSearchDashboardsMin]],\n        component_klass: Type[ComponentOpenSearch],\n        keep: bool = False,\n    ) -> None:\n        known_versions = self.versions\n        logging.info(f\"Known versions: {known_versions}\")\n        main_versions: Dict = {}\n        with TemporaryDirectory(keep=keep, chdir=True) as work_dir:\n            logging.info(f\"Checking out components into {work_dir.name}\")\n\n            # check out and build #main, 1.x, etc.\n            branches = min_klass.branches()\n\n            logging.info(f\"Checking {self.name} {branches} branches\")\n            for branch in branches:\n                c = min_klass.checkout(\n                    path=os.path.join(work_dir.name, self.name.replace(\" \", \"\"), branch),\n                    branch=branch,\n                )\n\n                version = c.version\n                logging.info(f\"{self.name}#{branch} is version {version}\")\n                if version not in main_versions.keys():\n                    main_versions[version] = [c]\n\n            if component_klass is not None:\n                # components can increment their own version first without incrementing min\n                manifest = self.latest\n                logging.info(f\"Examining components in the latest manifest of {manifest.build.name} ({manifest.build.version})\")\n                for component in manifest.components.values():\n                    if component.name == self.name:\n                        continue\n\n                    if type(component) is ComponentFromSource:\n                        logging.info(f\"Checking out {component.name}#main\")\n                        component = component_klass.checkout(\n                            name=component.name,\n                            path=os.path.join(work_dir.name, component.name),\n                            opensearch_version=manifest.build.version,\n                            repo_url=component.repository,\n                            branch=\"main\",\n                        )\n\n                        component_version = component.version\n                        if component_version:\n                            release_version = \".\".join(component_version.split(\".\")[:3])\n                            if release_version not in main_versions.keys():\n                                main_versions[release_version] = []\n                            main_versions[release_version].append(component)\n                            logging.info(f\"{component.name}#main is version {release_version} (from {component_version})\")\n\n            # summarize\n            logging.info(\"Found versions on main:\")\n            for main_version in main_versions.keys():\n                for component in main_versions[main_version]:\n                    logging.info(f\" {component.name}={main_version}\")\n\n            # generate new manifests\n            for release_version in sorted(main_versions.keys() - known_versions):\n                self.write_manifest(release_version, main_versions[release_version])\n                self.add_to_cron(release_version)\n                self.add_to_versionincrement_workflow(release_version)\n\n    def create_manifest(self, version: str, components: List = []) -> InputManifest:\n        templates_base_path = os.path.join(self.manifests_path(), \"templates\")\n        template_version_folder = version.split(\".\")[0] + \".x\"\n        template_full_path = os.path.join(templates_base_path, self.prefix, template_version_folder, \"manifest.yml\")\n        if not os.path.exists(template_full_path):\n            template_full_path = os.path.join(templates_base_path, self.prefix, \"default\", \"manifest.yml\")\n\n        manifest = InputManifest.from_file(open(template_full_path))\n\n        manifest.build.version = version\n        manifests_components = []\n\n        for component in components:\n            logging.info(f\" Adding {component.name}\")\n            manifests_components.append(component.to_dict())\n\n        manifest.components = InputComponents(manifests_components)  # type: ignore\n        return manifest\n\n    def write_manifest(self, version: str, components: List = []) -> None:\n        logging.info(f\"Creating new version: {version}\")\n        manifest = self.create_manifest(version, components)\n        manifest_dir = os.path.join(self.manifests_path(), version)\n        os.makedirs(manifest_dir, exist_ok=True)\n        manifest_path = os.path.join(manifest_dir, f\"{self.prefix}-{version}.yml\")\n        manifest.to_file(manifest_path)\n        logging.info(f\"Wrote {manifest_path}\")\n\n    def add_to_cron(self, version: str) -> None:\n        logging.info(f\"Adding new version to cron: {version}\")\n        jenkinsfile = self.cron_jenkinsfile()\n        with open(jenkinsfile, \"r\") as f:\n            data = f.read()\n\n        cron_entry = f\"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;TARGET_JOB_NAME=distribution-build-{self.prefix}\\n\"\n\n        if cron_entry in data:\n            raise ValueError(f\"{jenkinsfile} already contains an entry for {self.prefix} {version}\")\n\n        data = data.replace(\"parameterizedCron '''\\n\", f\"parameterizedCron '''\\n{' ' * 12}{cron_entry}\")\n\n        with open(jenkinsfile, \"w\") as f:\n            f.write(data)\n\n        logging.info(f\"Wrote {jenkinsfile}\")\n\n    def add_to_versionincrement_workflow(self, version: str) -> None:\n        versionincrement_workflow_file = self.versionincrement_workflow()\n        yaml = ruamel.yaml.YAML()\n        yaml.explicit_start = True  # type: ignore\n        yaml.preserve_quotes = True  # type: ignore\n\n        with open(versionincrement_workflow_file) as f:\n            data = yaml.load(f)\n\n        version_entry = []\n        major_version_entry = version.split(\".\")[0] + \".x\"\n        minor_version_entry = version.rsplit(\".\", 1)[0]\n        if minor_version_entry not in data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"]:\n            print(f\"Adding {minor_version_entry} to {versionincrement_workflow_file}\")\n            version_entry.append(minor_version_entry)\n        if major_version_entry not in data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"]:\n            print(f\"Adding {major_version_entry} to {versionincrement_workflow_file}\")\n            version_entry.append(major_version_entry)\n\n        if version_entry:\n            branch_list = list(data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"])\n            branch_list.extend(version_entry)\n            data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"] = branch_list\n            yaml.indent(mapping=2, sequence=4, offset=2)\n            with open(versionincrement_workflow_file, 'w') as f:\n                yaml.dump(data, f)\n            logging.info(\"Added new version to the version increment workflow\")\n", "path": "src/manifests_workflow/input_manifests.py"}], "after_files": [{"content": "# Copyright OpenSearch Contributors\n# SPDX-License-Identifier: Apache-2.0\n#\n# The OpenSearch Contributors require contributions made to\n# this file be licensed under the Apache-2.0 license or a\n# compatible open source license.\n\nimport glob\nimport logging\nimport os\nimport re\nfrom abc import abstractmethod\nfrom typing import Dict, List, Type, Union\n\nimport ruamel.yaml\n\nfrom manifests.component_manifest import ComponentFromSource\nfrom manifests.input_manifest import InputComponents, InputManifest\nfrom manifests.manifests import Manifests\nfrom manifests_workflow.component_opensearch import ComponentOpenSearch\nfrom manifests_workflow.component_opensearch_dashboards_min import ComponentOpenSearchDashboardsMin\nfrom manifests_workflow.component_opensearch_min import ComponentOpenSearchMin\nfrom system.temporary_directory import TemporaryDirectory\n\n\nclass InputManifests(Manifests):\n    BUILD_PLATFORM = {\n        \"opensearch\": \"linux macos windows\",\n        \"opensearch-dashboards\": \"linux windows\"\n    }\n\n    def __init__(self, name: str) -> None:\n        self.name = name\n        self.prefix = name.lower().replace(\" \", \"-\")\n        super().__init__(InputManifest, InputManifests.files(self.prefix))\n\n    @classmethod\n    def manifests_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"manifests\"))\n\n    @classmethod\n    def workflows_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \".github\", \"workflows\"))\n\n    @classmethod\n    def legacy_manifests_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"legacy-manifests\"))\n\n    @classmethod\n    def jenkins_path(self) -> str:\n        return os.path.realpath(os.path.join(os.path.dirname(__file__), \"..\", \"..\", \"jenkins\"))\n\n    @classmethod\n    def cron_jenkinsfile(self) -> str:\n        return os.path.join(self.jenkins_path(), \"check-for-build.jenkinsfile\")\n\n    @classmethod\n    def versionincrement_workflow(self) -> str:\n        return os.path.join(self.workflows_path(), \"increment-plugin-versions.yml\")\n\n    @classmethod\n    def files(self, name: str) -> List:\n        results = []\n        for path in [self.manifests_path(), self.legacy_manifests_path()]:\n            for filename in glob.glob(os.path.join(path, f\"**/{name}-*.yml\")):\n                # avoids the -maven manifest\n                match = re.search(rf\"^{name}-([0-9.]*).yml$\", os.path.basename(filename))\n                if match:\n                    results.append(filename)\n        return results\n\n    @abstractmethod\n    def update(\n        self,\n        min_klass: Union[Type[ComponentOpenSearchMin], Type[ComponentOpenSearchDashboardsMin]],\n        component_klass: Type[ComponentOpenSearch],\n        keep: bool = False,\n    ) -> None:\n        known_versions = self.versions\n        logging.info(f\"Known versions: {known_versions}\")\n        main_versions: Dict = {}\n        with TemporaryDirectory(keep=keep, chdir=True) as work_dir:\n            logging.info(f\"Checking out components into {work_dir.name}\")\n\n            # check out and build #main, 1.x, etc.\n            branches = min_klass.branches()\n\n            logging.info(f\"Checking {self.name} {branches} branches\")\n            for branch in branches:\n                c = min_klass.checkout(\n                    path=os.path.join(work_dir.name, self.name.replace(\" \", \"\"), branch),\n                    branch=branch,\n                )\n\n                version = c.version\n                logging.info(f\"{self.name}#{branch} is version {version}\")\n                if version not in main_versions.keys():\n                    main_versions[version] = [c]\n\n            if component_klass is not None:\n                # components can increment their own version first without incrementing min\n                manifest = self.latest\n                logging.info(f\"Examining components in the latest manifest of {manifest.build.name} ({manifest.build.version})\")\n                for component in manifest.components.values():\n                    if component.name == self.name:\n                        continue\n\n                    if type(component) is ComponentFromSource:\n                        logging.info(f\"Checking out {component.name}#main\")\n                        component = component_klass.checkout(\n                            name=component.name,\n                            path=os.path.join(work_dir.name, component.name),\n                            opensearch_version=manifest.build.version,\n                            repo_url=component.repository,\n                            branch=\"main\",\n                        )\n\n                        component_version = component.version\n                        if component_version:\n                            release_version = \".\".join(component_version.split(\".\")[:3])\n                            if release_version not in main_versions.keys():\n                                main_versions[release_version] = []\n                            main_versions[release_version].append(component)\n                            logging.info(f\"{component.name}#main is version {release_version} (from {component_version})\")\n\n            # summarize\n            logging.info(\"Found versions on main:\")\n            for main_version in main_versions.keys():\n                for component in main_versions[main_version]:\n                    logging.info(f\" {component.name}={main_version}\")\n\n            # generate new manifests\n            for release_version in sorted(main_versions.keys() - known_versions):\n                self.write_manifest(release_version, main_versions[release_version])\n                self.add_to_cron(release_version)\n                self.add_to_versionincrement_workflow(release_version)\n\n    def create_manifest(self, version: str, components: List = []) -> InputManifest:\n        templates_base_path = os.path.join(self.manifests_path(), \"templates\")\n        template_version_folder = version.split(\".\")[0] + \".x\"\n        template_full_path = os.path.join(templates_base_path, self.prefix, template_version_folder, \"manifest.yml\")\n        if not os.path.exists(template_full_path):\n            template_full_path = os.path.join(templates_base_path, self.prefix, \"default\", \"manifest.yml\")\n\n        manifest = InputManifest.from_file(open(template_full_path))\n\n        manifest.build.version = version\n        manifests_components = []\n\n        for component in components:\n            logging.info(f\" Adding {component.name}\")\n            manifests_components.append(component.to_dict())\n\n        manifest.components = InputComponents(manifests_components)  # type: ignore\n        return manifest\n\n    def write_manifest(self, version: str, components: List = []) -> None:\n        logging.info(f\"Creating new version: {version}\")\n        manifest = self.create_manifest(version, components)\n        manifest_dir = os.path.join(self.manifests_path(), version)\n        os.makedirs(manifest_dir, exist_ok=True)\n        manifest_path = os.path.join(manifest_dir, f\"{self.prefix}-{version}.yml\")\n        manifest.to_file(manifest_path)\n        logging.info(f\"Wrote {manifest_path}\")\n\n    def add_to_cron(self, version: str) -> None:\n        logging.info(f\"Adding new version to cron: {version}\")\n        jenkinsfile = self.cron_jenkinsfile()\n        with open(jenkinsfile, \"r\") as f:\n            data = f.read()\n\n        build_platform = self.BUILD_PLATFORM.get(self.prefix, \"linux\")\n\n        cron_entry = f\"H 1 * * * %INPUT_MANIFEST={version}/{self.prefix}-{version}.yml;\" \\\n                     f\"TARGET_JOB_NAME=distribution-build-{self.prefix};\" \\\n                     f\"BUILD_PLATFORM={build_platform}\\n\"\n\n        if cron_entry in data:\n            raise ValueError(f\"{jenkinsfile} already contains an entry for {self.prefix} {version}\")\n\n        data = data.replace(\"parameterizedCron '''\\n\", f\"parameterizedCron '''\\n{' ' * 12}{cron_entry}\")\n\n        with open(jenkinsfile, \"w\") as f:\n            f.write(data)\n\n        logging.info(f\"Wrote {jenkinsfile}\")\n\n    def add_to_versionincrement_workflow(self, version: str) -> None:\n        versionincrement_workflow_file = self.versionincrement_workflow()\n        yaml = ruamel.yaml.YAML()\n        yaml.explicit_start = True  # type: ignore\n        yaml.preserve_quotes = True  # type: ignore\n\n        with open(versionincrement_workflow_file) as f:\n            data = yaml.load(f)\n\n        version_entry = []\n        major_version_entry = version.split(\".\")[0] + \".x\"\n        minor_version_entry = version.rsplit(\".\", 1)[0]\n        if minor_version_entry not in data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"]:\n            print(f\"Adding {minor_version_entry} to {versionincrement_workflow_file}\")\n            version_entry.append(minor_version_entry)\n        if major_version_entry not in data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"]:\n            print(f\"Adding {major_version_entry} to {versionincrement_workflow_file}\")\n            version_entry.append(major_version_entry)\n\n        if version_entry:\n            branch_list = list(data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"])\n            branch_list.extend(version_entry)\n            data[\"jobs\"][\"plugin-version-increment-sync\"][\"strategy\"][\"matrix\"][\"branch\"] = branch_list\n            yaml.indent(mapping=2, sequence=4, offset=2)\n            with open(versionincrement_workflow_file, 'w') as f:\n                yaml.dump(data, f)\n            logging.info(\"Added new version to the version increment workflow\")\n", "path": "src/manifests_workflow/input_manifests.py"}]}