deep-code 0.0.1.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deep_code/__init__.py +24 -0
- deep_code/cli/__init__.py +3 -0
- deep_code/cli/main.py +22 -0
- deep_code/cli/publish.py +26 -0
- deep_code/constants.py +16 -0
- deep_code/tests/tools/__init__.py +3 -0
- deep_code/tests/tools/test_publish.py +120 -0
- deep_code/tests/utils/__init__.py +3 -0
- deep_code/tests/utils/test_dataset_stac_generator.py +219 -0
- deep_code/tests/utils/test_github_automation.py +120 -0
- deep_code/tests/utils/test_ogc_api_record.py +113 -0
- deep_code/tests/utils/test_ogc_record_generator.py +63 -0
- deep_code/tests/utils/test_osc_extension.py +117 -0
- deep_code/tools/__init__.py +3 -0
- deep_code/tools/check.py +4 -0
- deep_code/tools/new.py +5 -0
- deep_code/tools/publish.py +233 -0
- deep_code/tools/register.py +0 -0
- deep_code/tools/setup_ci.py +1 -0
- deep_code/tools/test.py +2 -0
- deep_code/utils/__init__.py +3 -0
- deep_code/utils/dataset_stac_generator.py +426 -0
- deep_code/utils/github_automation.py +122 -0
- deep_code/utils/ogc_api_record.py +94 -0
- deep_code/utils/ogc_record_generator.py +54 -0
- deep_code/utils/osc_extension.py +201 -0
- deep_code/version.py +22 -0
- deep_code-0.0.1.dev0.dist-info/LICENSE +21 -0
- deep_code-0.0.1.dev0.dist-info/METADATA +166 -0
- deep_code-0.0.1.dev0.dist-info/RECORD +33 -0
- deep_code-0.0.1.dev0.dist-info/WHEEL +5 -0
- deep_code-0.0.1.dev0.dist-info/entry_points.txt +2 -0
- deep_code-0.0.1.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
from datetime import datetime, timezone
|
|
3
|
+
|
|
4
|
+
from deep_code.constants import DEFAULT_THEME_SCHEME
|
|
5
|
+
from deep_code.utils.ogc_record_generator import OSCWorkflowOGCApiRecordGenerator
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestOSCWorkflowOGCApiRecordGenerator(unittest.TestCase):
|
|
9
|
+
def test_build_contact_objects(self):
|
|
10
|
+
contacts_list = [
|
|
11
|
+
{"name": "Alice", "organization": "Org A", "position": "Researcher"},
|
|
12
|
+
{"name": "Bob", "organization": "Org B", "position": "Developer"},
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
result = OSCWorkflowOGCApiRecordGenerator.build_contact_objects(contacts_list)
|
|
16
|
+
|
|
17
|
+
self.assertEqual(len(result), 2)
|
|
18
|
+
self.assertEqual(result[0].name, "Alice")
|
|
19
|
+
self.assertEqual(result[0].organization, "Org A")
|
|
20
|
+
self.assertEqual(result[0].position, "Researcher")
|
|
21
|
+
self.assertEqual(result[1].name, "Bob")
|
|
22
|
+
self.assertEqual(result[1].organization, "Org B")
|
|
23
|
+
self.assertEqual(result[1].position, "Developer")
|
|
24
|
+
|
|
25
|
+
def test_build_theme(self):
|
|
26
|
+
osc_themes = ["theme1", "theme2"]
|
|
27
|
+
|
|
28
|
+
theme = OSCWorkflowOGCApiRecordGenerator.build_theme(osc_themes)
|
|
29
|
+
|
|
30
|
+
self.assertEqual(len(theme.concepts), 2)
|
|
31
|
+
self.assertEqual(theme.concepts[0].id, "theme1")
|
|
32
|
+
self.assertEqual(theme.concepts[1].id, "theme2")
|
|
33
|
+
self.assertEqual(theme.scheme, DEFAULT_THEME_SCHEME)
|
|
34
|
+
|
|
35
|
+
def test_build_record_properties(self):
|
|
36
|
+
generator = OSCWorkflowOGCApiRecordGenerator()
|
|
37
|
+
properties = {
|
|
38
|
+
"title": "Test Workflow",
|
|
39
|
+
"description": "A test description",
|
|
40
|
+
"themes": ["theme1"],
|
|
41
|
+
"jupyter_kernel_info": {
|
|
42
|
+
"name": "deepesdl-xcube-1.7.1",
|
|
43
|
+
"python_version": 3.11,
|
|
44
|
+
"env_file": "https://git/env.yml",
|
|
45
|
+
},
|
|
46
|
+
}
|
|
47
|
+
contacts = [
|
|
48
|
+
{"name": "Alice", "organization": "Org A", "position": "Researcher"}
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
record_properties = generator.build_record_properties(properties, contacts)
|
|
52
|
+
|
|
53
|
+
now_iso = datetime.now(timezone.utc).isoformat()
|
|
54
|
+
|
|
55
|
+
self.assertEqual(record_properties.title, "Test Workflow")
|
|
56
|
+
self.assertEqual(record_properties.description, "A test description")
|
|
57
|
+
self.assertEqual(len(record_properties.contacts), 1)
|
|
58
|
+
self.assertEqual(record_properties.contacts[0].name, "Alice")
|
|
59
|
+
self.assertEqual(len(record_properties.themes), 1)
|
|
60
|
+
self.assertEqual(record_properties.themes[0].concepts[0].id, "theme1")
|
|
61
|
+
self.assertEqual(record_properties.type, "workflow")
|
|
62
|
+
self.assertTrue("created" in record_properties.__dict__)
|
|
63
|
+
self.assertTrue("updated" in record_properties.__dict__)
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
|
|
3
|
+
from pystac import Collection, Extent, SpatialExtent, TemporalExtent
|
|
4
|
+
|
|
5
|
+
from deep_code.utils.osc_extension import OscExtension
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class TestOscExtension(unittest.TestCase):
|
|
9
|
+
def setUp(self):
|
|
10
|
+
"""Set up a test Collection object and attach the OscExtension."""
|
|
11
|
+
self.collection = Collection(
|
|
12
|
+
id="test-collection",
|
|
13
|
+
description="Test collection for unit tests",
|
|
14
|
+
extent=Extent(
|
|
15
|
+
spatial=SpatialExtent([[-180, -90, 180, 90]]),
|
|
16
|
+
temporal=TemporalExtent(
|
|
17
|
+
[["2022-01-01T00:00:00Z", "2023-01-01T00:00:00Z"]]
|
|
18
|
+
),
|
|
19
|
+
),
|
|
20
|
+
stac_extensions=[],
|
|
21
|
+
)
|
|
22
|
+
OscExtension.add_to(self.collection)
|
|
23
|
+
|
|
24
|
+
def test_osc_status(self):
|
|
25
|
+
"""Test the osc:status property."""
|
|
26
|
+
extension = OscExtension.ext(self.collection)
|
|
27
|
+
extension.osc_status = "ongoing"
|
|
28
|
+
self.assertEqual(extension.osc_status, "ongoing")
|
|
29
|
+
|
|
30
|
+
def test_osc_region(self):
|
|
31
|
+
"""Test the osc:region property."""
|
|
32
|
+
extension = OscExtension.ext(self.collection)
|
|
33
|
+
extension.osc_region = "Mediterranean region"
|
|
34
|
+
self.assertEqual(extension.osc_region, "Mediterranean region")
|
|
35
|
+
|
|
36
|
+
def test_osc_themes(self):
|
|
37
|
+
"""Test the osc:themes property."""
|
|
38
|
+
extension = OscExtension.ext(self.collection)
|
|
39
|
+
extension.osc_themes = ["land", "ocean"]
|
|
40
|
+
self.assertEqual(extension.osc_themes, ["land", "ocean"])
|
|
41
|
+
|
|
42
|
+
def test_osc_missions(self):
|
|
43
|
+
"""Test the osc:missions property."""
|
|
44
|
+
extension = OscExtension.ext(self.collection)
|
|
45
|
+
extension.osc_missions = ["mission1", "mission2"]
|
|
46
|
+
self.assertEqual(extension.osc_missions, ["mission1", "mission2"])
|
|
47
|
+
|
|
48
|
+
def test_keywords(self):
|
|
49
|
+
"""Test the keywords property."""
|
|
50
|
+
extension = OscExtension.ext(self.collection)
|
|
51
|
+
extension.keywords = ["Hydrology", "Remote Sensing"]
|
|
52
|
+
self.assertEqual(extension.keywords, ["Hydrology", "Remote Sensing"])
|
|
53
|
+
|
|
54
|
+
def test_cf_parameters(self):
|
|
55
|
+
"""Test the cf:parameter property."""
|
|
56
|
+
extension = OscExtension.ext(self.collection)
|
|
57
|
+
extension.cf_parameter = [{"name": "hydrology-4D"}]
|
|
58
|
+
self.assertEqual(extension.cf_parameter, [{"name": "hydrology-4D"}])
|
|
59
|
+
|
|
60
|
+
def test_created_updated(self):
|
|
61
|
+
"""Test the created and updated properties."""
|
|
62
|
+
extension = OscExtension.ext(self.collection)
|
|
63
|
+
extension.created = "2023-12-21T11:50:17Z"
|
|
64
|
+
extension.updated = "2023-12-21T11:50:17Z"
|
|
65
|
+
self.assertEqual(extension.created, "2023-12-21T11:50:17Z")
|
|
66
|
+
self.assertEqual(extension.updated, "2023-12-21T11:50:17Z")
|
|
67
|
+
|
|
68
|
+
def test_set_extent(self):
|
|
69
|
+
"""Test setting spatial and temporal extent."""
|
|
70
|
+
extension = OscExtension.ext(self.collection)
|
|
71
|
+
spatial = [[-5.7, 28.3, 37.7, 48.1]]
|
|
72
|
+
temporal = [["2014-12-31T12:00:00Z", "2022-10-06T12:00:00Z"]]
|
|
73
|
+
extension.set_extent(spatial, temporal)
|
|
74
|
+
|
|
75
|
+
self.assertEqual(self.collection.extent.spatial.bboxes, spatial)
|
|
76
|
+
self.assertEqual(self.collection.extent.temporal.intervals, temporal)
|
|
77
|
+
|
|
78
|
+
def test_validation_success(self):
|
|
79
|
+
"""Test validation with all required fields."""
|
|
80
|
+
extension = OscExtension.ext(self.collection)
|
|
81
|
+
extension.osc_type = "product"
|
|
82
|
+
extension.osc_project = "test-project"
|
|
83
|
+
extension.osc_status = "ongoing"
|
|
84
|
+
extension.validate_extension() # Should not raise an exception
|
|
85
|
+
|
|
86
|
+
def test_add_osc_extension(self):
|
|
87
|
+
osc_ext = OscExtension.add_to(self.collection)
|
|
88
|
+
self.assertEqual(OscExtension.get_schema_uri(), self.collection.stac_extensions)
|
|
89
|
+
self.assertIsInstance(osc_ext, OscExtension)
|
|
90
|
+
|
|
91
|
+
def test_has_extension(self):
|
|
92
|
+
self.collection.stac_extensions = []
|
|
93
|
+
self.assertFalse(OscExtension.has_extension(self.collection))
|
|
94
|
+
OscExtension.add_to(self.collection)
|
|
95
|
+
self.assertTrue(OscExtension.has_extension(self.collection))
|
|
96
|
+
|
|
97
|
+
def test_set_and_get_properties(self):
|
|
98
|
+
osc_ext = OscExtension.add_to(self.collection)
|
|
99
|
+
osc_ext.osc_type = "example-type"
|
|
100
|
+
osc_ext.osc_project = "example-project"
|
|
101
|
+
osc_ext.osc_product = "example-product"
|
|
102
|
+
osc_ext.osc_theme = ["example-theme"]
|
|
103
|
+
osc_ext.osc_variables = ["var1", "var2", "var3"]
|
|
104
|
+
|
|
105
|
+
self.assertEqual(osc_ext.osc_type, "example-type")
|
|
106
|
+
self.assertEqual(osc_ext.osc_project, "example-project")
|
|
107
|
+
self.assertEqual(osc_ext.osc_product, "example-product")
|
|
108
|
+
self.assertEqual(osc_ext.osc_theme, ["example-theme"])
|
|
109
|
+
self.assertListEqual(osc_ext.osc_variables, ["var1", "var2", "var3"])
|
|
110
|
+
|
|
111
|
+
def test_validation_missing_fields(self):
|
|
112
|
+
"""Test validation with missing required fields."""
|
|
113
|
+
extension = OscExtension.ext(self.collection)
|
|
114
|
+
with self.assertRaises(ValueError) as context:
|
|
115
|
+
extension.validate_extension()
|
|
116
|
+
self.assertIn("Missing required fields", str(context.exception))
|
|
117
|
+
self.assertIn("osc:type", str(context.exception))
|
deep_code/tools/check.py
ADDED
deep_code/tools/new.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
"""Logic for initializing repositories
|
|
2
|
+
Initialize a GitHub repository with the proposed configurations files, an initial
|
|
3
|
+
workflow notebook template (e.g. workflow.ipynb), a template Python package (code and
|
|
4
|
+
pyproject.toml), and a template setup for documentation (e.g., using mkdocs),
|
|
5
|
+
setup of thebuild pipeline"""
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
|
|
3
|
+
# Copyright (c) 2025 by Brockmann Consult GmbH
|
|
4
|
+
# Permissions are hereby granted under the terms of the MIT License:
|
|
5
|
+
# https://opensource.org/licenses/MIT.
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
|
|
10
|
+
import fsspec
|
|
11
|
+
import yaml
|
|
12
|
+
|
|
13
|
+
from deep_code.constants import (
|
|
14
|
+
OSC_BRANCH_NAME,
|
|
15
|
+
OSC_REPO_NAME,
|
|
16
|
+
OSC_REPO_OWNER,
|
|
17
|
+
WF_BRANCH_NAME,
|
|
18
|
+
)
|
|
19
|
+
from deep_code.utils.dataset_stac_generator import OscDatasetStacGenerator
|
|
20
|
+
from deep_code.utils.github_automation import GitHubAutomation
|
|
21
|
+
from deep_code.utils.ogc_api_record import OgcRecord
|
|
22
|
+
from deep_code.utils.ogc_record_generator import OSCWorkflowOGCApiRecordGenerator
|
|
23
|
+
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
logging.basicConfig(level=logging.INFO)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class GitHubPublisher:
|
|
29
|
+
"""
|
|
30
|
+
Base class providing:
|
|
31
|
+
- Reading .gitaccess for credentials
|
|
32
|
+
- Common GitHub automation steps (fork, clone, branch, file commit, pull request)
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
def __init__(self):
|
|
36
|
+
with fsspec.open(".gitaccess", "r") as file:
|
|
37
|
+
git_config = yaml.safe_load(file) or {}
|
|
38
|
+
self.github_username = git_config.get("github-username")
|
|
39
|
+
self.github_token = git_config.get("github-token")
|
|
40
|
+
if not self.github_username or not self.github_token:
|
|
41
|
+
raise ValueError("GitHub credentials are missing in the `.gitaccess` file.")
|
|
42
|
+
|
|
43
|
+
self.github_automation = GitHubAutomation(
|
|
44
|
+
self.github_username, self.github_token, OSC_REPO_OWNER, OSC_REPO_NAME
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def publish_files(
|
|
48
|
+
self,
|
|
49
|
+
branch_name: str,
|
|
50
|
+
file_dict: dict[str, dict],
|
|
51
|
+
commit_message: str,
|
|
52
|
+
pr_title: str,
|
|
53
|
+
pr_body: str,
|
|
54
|
+
) -> str:
|
|
55
|
+
"""Publish multiple files to a new branch and open a PR.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
branch_name: Branch name to create (e.g. "osc-branch-collectionid").
|
|
59
|
+
file_dict: { file_path: file_content_dict } for each file to commit.
|
|
60
|
+
commit_message: Commit message for all changes.
|
|
61
|
+
pr_title: Title of the pull request.
|
|
62
|
+
pr_body: Description/body of the pull request.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
URL of the created pull request.
|
|
66
|
+
"""
|
|
67
|
+
try:
|
|
68
|
+
logger.info("Forking and cloning repository...")
|
|
69
|
+
self.github_automation.fork_repository()
|
|
70
|
+
self.github_automation.clone_repository()
|
|
71
|
+
self.github_automation.create_branch(branch_name)
|
|
72
|
+
|
|
73
|
+
# Add each file to the branch
|
|
74
|
+
for file_path, content in file_dict.items():
|
|
75
|
+
logger.info(f"Adding {file_path} to {branch_name}")
|
|
76
|
+
self.github_automation.add_file(file_path, content)
|
|
77
|
+
|
|
78
|
+
# Commit and push
|
|
79
|
+
self.github_automation.commit_and_push(branch_name, commit_message)
|
|
80
|
+
|
|
81
|
+
# Create pull request
|
|
82
|
+
pr_url = self.github_automation.create_pull_request(
|
|
83
|
+
branch_name, pr_title, pr_body
|
|
84
|
+
)
|
|
85
|
+
logger.info(f"Pull request created: {pr_url}")
|
|
86
|
+
return pr_url
|
|
87
|
+
|
|
88
|
+
finally:
|
|
89
|
+
# Cleanup local clone
|
|
90
|
+
self.github_automation.clean_up()
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class DatasetPublisher:
|
|
94
|
+
"""Publishes products (datasets) to the OSC GitHub repository.
|
|
95
|
+
Inherits from BasePublisher for GitHub publishing logic.
|
|
96
|
+
"""
|
|
97
|
+
|
|
98
|
+
def __init__(self):
|
|
99
|
+
# Composition
|
|
100
|
+
self.gh_publisher = GitHubPublisher()
|
|
101
|
+
|
|
102
|
+
def publish_dataset(self, dataset_config_path: str):
|
|
103
|
+
"""Publish a product collection to the specified GitHub repository."""
|
|
104
|
+
with fsspec.open(dataset_config_path, "r") as file:
|
|
105
|
+
dataset_config = yaml.safe_load(file) or {}
|
|
106
|
+
|
|
107
|
+
dataset_id = dataset_config.get("dataset_id")
|
|
108
|
+
collection_id = dataset_config.get("collection_id")
|
|
109
|
+
documentation_link = dataset_config.get("documentation_link")
|
|
110
|
+
access_link = dataset_config.get("access_link")
|
|
111
|
+
dataset_status = dataset_config.get("dataset_status")
|
|
112
|
+
osc_region = dataset_config.get("osc_region")
|
|
113
|
+
osc_themes = dataset_config.get("osc_themes")
|
|
114
|
+
cf_params = dataset_config.get("cf_parameter")
|
|
115
|
+
|
|
116
|
+
if not dataset_id or not collection_id:
|
|
117
|
+
raise ValueError("Dataset ID or Collection ID missing in the config.")
|
|
118
|
+
|
|
119
|
+
logger.info("Generating STAC collection...")
|
|
120
|
+
|
|
121
|
+
generator = OscDatasetStacGenerator(
|
|
122
|
+
dataset_id=dataset_id,
|
|
123
|
+
collection_id=collection_id,
|
|
124
|
+
documentation_link=documentation_link,
|
|
125
|
+
access_link=access_link,
|
|
126
|
+
osc_status=dataset_status,
|
|
127
|
+
osc_region=osc_region,
|
|
128
|
+
osc_themes=osc_themes,
|
|
129
|
+
cf_params=cf_params,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
variable_ids = generator.get_variable_ids()
|
|
133
|
+
ds_collection = generator.build_dataset_stac_collection()
|
|
134
|
+
|
|
135
|
+
# Prepare a dictionary of file paths and content
|
|
136
|
+
file_dict = {}
|
|
137
|
+
product_path = f"products/{collection_id}/collection.json"
|
|
138
|
+
file_dict[product_path] = ds_collection.to_dict()
|
|
139
|
+
|
|
140
|
+
# Add or update variable files
|
|
141
|
+
for var_id in variable_ids:
|
|
142
|
+
var_file_path = f"variables/{var_id}/catalog.json"
|
|
143
|
+
if not self.gh_publisher.github_automation.file_exists(var_file_path):
|
|
144
|
+
logger.info(
|
|
145
|
+
f"Variable catalog for {var_id} does not exist. Creating..."
|
|
146
|
+
)
|
|
147
|
+
var_metadata = generator.variables_metadata.get(var_id)
|
|
148
|
+
var_catalog = generator.build_variable_catalog(var_metadata)
|
|
149
|
+
file_dict[var_file_path] = var_catalog.to_dict()
|
|
150
|
+
else:
|
|
151
|
+
logger.info(
|
|
152
|
+
f"Variable catalog already exists for {var_id}, adding product link."
|
|
153
|
+
)
|
|
154
|
+
full_path = (
|
|
155
|
+
Path(self.gh_publisher.github_automation.local_clone_dir)
|
|
156
|
+
/ var_file_path
|
|
157
|
+
)
|
|
158
|
+
updated_catalog = generator.update_existing_variable_catalog(
|
|
159
|
+
full_path, var_id
|
|
160
|
+
)
|
|
161
|
+
file_dict[var_file_path] = updated_catalog.to_dict()
|
|
162
|
+
|
|
163
|
+
# Create branch name, commit message, PR info
|
|
164
|
+
branch_name = f"{OSC_BRANCH_NAME}-{collection_id}"
|
|
165
|
+
commit_message = f"Add new dataset collection: {collection_id}"
|
|
166
|
+
pr_title = "Add new dataset collection"
|
|
167
|
+
pr_body = "This PR adds a new dataset collection to the repository."
|
|
168
|
+
|
|
169
|
+
# Publish all files in one go
|
|
170
|
+
pr_url = self.gh_publisher.publish_files(
|
|
171
|
+
branch_name=branch_name,
|
|
172
|
+
file_dict=file_dict,
|
|
173
|
+
commit_message=commit_message,
|
|
174
|
+
pr_title=pr_title,
|
|
175
|
+
pr_body=pr_body,
|
|
176
|
+
)
|
|
177
|
+
|
|
178
|
+
logger.info(f"Pull request created: {pr_url}")
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
class WorkflowPublisher:
|
|
182
|
+
"""Publishes workflows to the OSC GitHub repository."""
|
|
183
|
+
|
|
184
|
+
def __init__(self):
|
|
185
|
+
self.gh_publisher = GitHubPublisher()
|
|
186
|
+
|
|
187
|
+
@staticmethod
|
|
188
|
+
def _normalize_name(name: str | None) -> str | None:
|
|
189
|
+
return name.replace(" ", "-").lower() if name else None
|
|
190
|
+
|
|
191
|
+
def publish_workflow(self, workflow_config_path: str):
|
|
192
|
+
with fsspec.open(workflow_config_path, "r") as file:
|
|
193
|
+
workflow_config = yaml.safe_load(file) or {}
|
|
194
|
+
|
|
195
|
+
workflow_id = self._normalize_name(workflow_config.get("workflow_id"))
|
|
196
|
+
if not workflow_id:
|
|
197
|
+
raise ValueError("workflow_id is missing in workflow config.")
|
|
198
|
+
|
|
199
|
+
properties_list = workflow_config.get("properties", [])
|
|
200
|
+
contacts = workflow_config.get("contact", [])
|
|
201
|
+
links = workflow_config.get("links", [])
|
|
202
|
+
|
|
203
|
+
logger.info("Generating OGC API Record for the workflow...")
|
|
204
|
+
rg = OSCWorkflowOGCApiRecordGenerator()
|
|
205
|
+
wf_record_properties = rg.build_record_properties(properties_list, contacts)
|
|
206
|
+
|
|
207
|
+
ogc_record = OgcRecord(
|
|
208
|
+
id=workflow_id,
|
|
209
|
+
type="Feature",
|
|
210
|
+
time={},
|
|
211
|
+
properties=wf_record_properties,
|
|
212
|
+
links=links,
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
file_path = f"workflow/{workflow_id}/collection.json"
|
|
216
|
+
|
|
217
|
+
# Prepare the single file dict
|
|
218
|
+
file_dict = {file_path: ogc_record.to_dict()}
|
|
219
|
+
|
|
220
|
+
branch_name = f"{WF_BRANCH_NAME}-{workflow_id}"
|
|
221
|
+
commit_message = f"Add new workflow: {workflow_id}"
|
|
222
|
+
pr_title = "Add new workflow"
|
|
223
|
+
pr_body = "This PR adds a new workflow to the OSC repository."
|
|
224
|
+
|
|
225
|
+
pr_url = self.gh_publisher.publish_files(
|
|
226
|
+
branch_name=branch_name,
|
|
227
|
+
file_dict=file_dict,
|
|
228
|
+
commit_message=commit_message,
|
|
229
|
+
pr_title=pr_title,
|
|
230
|
+
pr_body=pr_body,
|
|
231
|
+
)
|
|
232
|
+
|
|
233
|
+
logger.info(f"Pull request created: {pr_url}")
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Logic for setting up build pipelines"""
|
deep_code/tools/test.py
ADDED