artefacts-cli 0.9.4__tar.gz → 0.9.5__tar.gz
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.
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/CHANGELOG.md +6 -1
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/PKG-INFO +4 -1
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/__init__.py +17 -7
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/config.py +18 -9
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/locales/art.pot +15 -14
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/locales/base.pot +15 -14
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/locales/click.pot +2 -2
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/locales/ja_JP/LC_MESSAGES/artefacts.po +18 -15
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/version.py +2 -2
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/PKG-INFO +4 -1
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/SOURCES.txt +1 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/requires.txt +4 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/bin/release +5 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/pyproject.toml +5 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/pytest.ini +4 -0
- artefacts_cli-0.9.5/scripts/whats_latest.rb +11 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_warp.py +137 -3
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_warp_run.py +62 -1
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/conftest.py +11 -2
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/.pyre_configuration +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/README.md +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/README_INTERNAL.md +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/app.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/app_containers.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/app_containers.pyi +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/bagparser.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/constants.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/containers/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/containers/docker_cm.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/containers/docker_utils.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/containers/utils.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/errors.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/helpers.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/i18n.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/logger.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/other.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/parameters.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/ros1.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/ros2.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/utils.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/utils_ros.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/copava/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/wrappers/artefacts_ros1_meta.launch +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts.yaml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/dependency_links.txt +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/entry_points.txt +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts_cli.egg-info/top_level.txt +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/test_run_remote.yaml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/CMakeLists.txt +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/test_meta.launch +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/test_turtle.launch +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/launch/turtle_odometry.launch +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/package.xml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/setup.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/TestTurtle.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_odom.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_post_process.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_trajectory.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/test/viz_turtle_odom.xml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim2/launch_turtle.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/infra-tests/turtlesim2/sample_node.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/setup.cfg +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/containers/__init__.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/containers/test_docker.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/containers/test_utils.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_app_containers.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_cli.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_config_validation.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_other.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_parameters.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_ros1.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_ros2.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_utils.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/cli/test_utils_ros.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/fixtures/artefacts.yaml.template +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/fixtures/artefacts_deprecated.yaml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/fixtures/bad_launch_test.py +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/fixtures/test_junit.xml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/fixtures/warp-env-param.yaml +0 -0
- {artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/tests/utils/docker_mock.py +0 -0
@@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
TODO and upcoming
|
11
|
+
|
12
|
+
## [0.9.5] - 2025-06-30
|
13
|
+
|
10
14
|
### Added
|
11
15
|
|
12
16
|
- API calls are automatically retried up to 3 times on server-side 502, 503, 504 errors (#264)
|
@@ -116,7 +120,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
116
120
|
- Local metrics errors do not block publication of results.
|
117
121
|
- Introduction of Black formatting.
|
118
122
|
|
119
|
-
[unreleased]: https://github.com/art-e-fact/artefacts-client/compare/0.9.
|
123
|
+
[unreleased]: https://github.com/art-e-fact/artefacts-client/compare/0.9.5...HEAD
|
124
|
+
[0.9.5]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.9.5
|
120
125
|
[0.9.3]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.9.3
|
121
126
|
[0.8.0]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.8.0
|
122
127
|
[0.7.0]: https://github.com/art-e-fact/artefacts-client/releases/tag/0.7.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: artefacts_cli
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.5
|
4
4
|
Author-email: FD <fabian@artefacts.com>, AGC <alejandro@artefacts.com>, TN <tomo@artefacts.com>, EP <eric@artefacts.com>
|
5
5
|
License-Expression: Apache-2.0
|
6
6
|
Project-URL: Homepage, https://github.com/art-e-fact/artefacts-client
|
@@ -42,6 +42,9 @@ Requires-Dist: python-markdown-math; extra == "dev"
|
|
42
42
|
Requires-Dist: ruff>=0.9.2; extra == "dev"
|
43
43
|
Requires-Dist: setuptools_scm>=8; extra == "dev"
|
44
44
|
Requires-Dist: twine; extra == "dev"
|
45
|
+
Provides-Extra: dev-extended
|
46
|
+
Requires-Dist: artefacts_cli[dev]; extra == "dev-extended"
|
47
|
+
Requires-Dist: pytest-watch; extra == "dev-extended"
|
45
48
|
|
46
49
|
# Artefacts CLI
|
47
50
|
|
@@ -32,7 +32,15 @@ except PackageNotFoundError:
|
|
32
32
|
__version__ = "0.0.0"
|
33
33
|
|
34
34
|
|
35
|
-
class
|
35
|
+
class ArtefactsAPIError(Exception):
|
36
|
+
"""
|
37
|
+
Tentative base error class for Artefacts API interactions
|
38
|
+
"""
|
39
|
+
|
40
|
+
pass
|
41
|
+
|
42
|
+
|
43
|
+
class AuthenticationError(ArtefactsAPIError):
|
36
44
|
"""Raised when artefacts authentication failed"""
|
37
45
|
|
38
46
|
pass
|
@@ -74,6 +82,7 @@ class WarpJob:
|
|
74
82
|
if self.job_id is None:
|
75
83
|
# Only create a new job if job_id is not specified
|
76
84
|
data = {
|
85
|
+
"project_id": self.project_id,
|
77
86
|
"start": round(self.start),
|
78
87
|
"status": "in progress",
|
79
88
|
"params": json.dumps(self.params),
|
@@ -100,7 +109,7 @@ class WarpJob:
|
|
100
109
|
)
|
101
110
|
)
|
102
111
|
logger.warning(response.text)
|
103
|
-
raise
|
112
|
+
raise ArtefactsAPIError(str(response.status_code))
|
104
113
|
self.job_id = response.json()["job_id"]
|
105
114
|
self.output_path = self.params.get("output_path", f"/tmp/{self.job_id}")
|
106
115
|
os.makedirs(self.output_path, exist_ok=True)
|
@@ -109,20 +118,21 @@ class WarpJob:
|
|
109
118
|
def log_tests_result(self, success):
|
110
119
|
self.success = success
|
111
120
|
|
112
|
-
def update(self, last_run_success: bool):
|
121
|
+
def update(self, last_run_success: bool) -> bool:
|
113
122
|
end = datetime.now(timezone.utc).timestamp()
|
114
123
|
if self.dryrun:
|
115
|
-
return
|
124
|
+
return True
|
116
125
|
# Log metadata
|
117
126
|
data = {
|
127
|
+
"project_id": self.project_id,
|
118
128
|
"end": round(end),
|
119
129
|
"duration": round(end - self.start),
|
120
130
|
"success": last_run_success,
|
121
131
|
"status": "finished", # need to be determined based on all runs
|
122
132
|
}
|
123
|
-
self.api_conf.update("job", self.job_id, data)
|
133
|
+
response = self.api_conf.update("job", self.job_id, data)
|
124
134
|
|
125
|
-
return
|
135
|
+
return response.status_code == 200
|
126
136
|
|
127
137
|
def new_run(self, scenario):
|
128
138
|
run = WarpRun(self, scenario["name"], scenario, self.n_runs)
|
@@ -173,7 +183,7 @@ class WarpRun:
|
|
173
183
|
)
|
174
184
|
)
|
175
185
|
self.logger.warning(response.text)
|
176
|
-
raise
|
186
|
+
raise ArtefactsAPIError(str(response.status_code))
|
177
187
|
return
|
178
188
|
|
179
189
|
def log_params(self, params):
|
@@ -25,7 +25,11 @@ urllib3logger.setLevel(logging.ERROR)
|
|
25
25
|
|
26
26
|
class APIConf:
|
27
27
|
def __init__(
|
28
|
-
self,
|
28
|
+
self,
|
29
|
+
project_name: str,
|
30
|
+
api_version: str,
|
31
|
+
job_name: Optional[str] = None,
|
32
|
+
session: Optional[Session] = None,
|
29
33
|
) -> None:
|
30
34
|
config = get_conf_from_file()
|
31
35
|
if project_name in config:
|
@@ -76,7 +80,7 @@ class APIConf:
|
|
76
80
|
#
|
77
81
|
# Retry settings
|
78
82
|
#
|
79
|
-
self.session = Session()
|
83
|
+
self.session = session or Session()
|
80
84
|
retries = Retry(
|
81
85
|
total=3,
|
82
86
|
backoff_factor=0.1,
|
@@ -84,21 +88,23 @@ class APIConf:
|
|
84
88
|
allowed_methods=Retry.DEFAULT_ALLOWED_METHODS | {"POST"},
|
85
89
|
)
|
86
90
|
# Default connect timeout set to a small value above the default 3s for TCP
|
87
|
-
# Default read timeout a
|
91
|
+
# Default read timeout a typical value. Does not scale when too aggressive
|
88
92
|
# (note: read timeout is between byte sent, not the whole read)
|
89
|
-
self.request_timeout = (3.03,
|
93
|
+
self.request_timeout = (3.03, 27)
|
90
94
|
self.session.mount("https://", HTTPAdapter(max_retries=retries))
|
91
95
|
|
92
96
|
@contextmanager
|
93
97
|
def _api(self):
|
94
98
|
try:
|
95
99
|
yield self.session
|
96
|
-
except ConnectionError:
|
100
|
+
except ConnectionError as e:
|
97
101
|
raise click.ClickException(
|
98
102
|
localise(
|
99
|
-
"Unable to
|
100
|
-
"
|
101
|
-
"
|
103
|
+
"Unable to complete the operation: Network error.\n"
|
104
|
+
"This may be a problem with an Artefacts server, or your network.\n"
|
105
|
+
"Please try again in a moment or confirm your internet connection.\n"
|
106
|
+
"If the problem persists, please contact us (info@artefacts.com)!\n"
|
107
|
+
f"All we know: {e}"
|
102
108
|
)
|
103
109
|
)
|
104
110
|
|
@@ -173,13 +179,16 @@ class APIConf:
|
|
173
179
|
|
174
180
|
Note this is temporary helper, as we expect to turn files as
|
175
181
|
first-order resource at the API level, so move to CRUD model, etc.
|
182
|
+
|
183
|
+
This facility disables all timeouts, as uploads can be very
|
184
|
+
long, and we'd better wait.
|
176
185
|
"""
|
177
186
|
with self._api() as session:
|
178
187
|
return session.post(
|
179
188
|
url,
|
180
189
|
data=data,
|
181
190
|
files=files,
|
182
|
-
timeout=
|
191
|
+
timeout=None,
|
183
192
|
)
|
184
193
|
|
185
194
|
def direct(self, verb: str) -> Callable:
|
@@ -6,9 +6,9 @@
|
|
6
6
|
#, fuzzy
|
7
7
|
msgid ""
|
8
8
|
msgstr ""
|
9
|
-
"Project-Id-Version: artefacts 0.9.
|
9
|
+
"Project-Id-Version: artefacts 0.9.5.dev7\n"
|
10
10
|
"Report-Msgid-Bugs-To: dev@artefacts.com\n"
|
11
|
-
"POT-Creation-Date: 2025-06-
|
11
|
+
"POT-Creation-Date: 2025-06-24 09:46+0900\n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -22,33 +22,33 @@ msgstr ""
|
|
22
22
|
msgid "Could not determine package version: {error_message}. Default to 0.0.0"
|
23
23
|
msgstr ""
|
24
24
|
|
25
|
-
#: artefacts/cli/__init__.py:
|
25
|
+
#: artefacts/cli/__init__.py:98
|
26
26
|
#, python-brace-format
|
27
27
|
msgid "Error on job creation: {status_code}"
|
28
28
|
msgstr ""
|
29
29
|
|
30
|
-
#: artefacts/cli/__init__.py:
|
30
|
+
#: artefacts/cli/__init__.py:172
|
31
31
|
#, python-brace-format
|
32
32
|
msgid "Error on scenario creation: {status_code}"
|
33
33
|
msgstr ""
|
34
34
|
|
35
|
-
#: artefacts/cli/__init__.py:
|
35
|
+
#: artefacts/cli/__init__.py:281
|
36
36
|
msgid ""
|
37
37
|
"Files generated by the job are not uploaded to Artefacts, including the "
|
38
38
|
"ones specified in output_dirs"
|
39
39
|
msgstr ""
|
40
40
|
|
41
|
-
#: artefacts/cli/__init__.py:
|
41
|
+
#: artefacts/cli/__init__.py:293
|
42
42
|
#, python-brace-format
|
43
43
|
msgid "Uploading {file_name} ({file_size:.2f} MB)"
|
44
44
|
msgstr ""
|
45
45
|
|
46
|
-
#: artefacts/cli/__init__.py:
|
46
|
+
#: artefacts/cli/__init__.py:304
|
47
47
|
#, python-brace-format
|
48
48
|
msgid "File too large: {file_name} could not be uploaded"
|
49
49
|
msgstr ""
|
50
50
|
|
51
|
-
#: artefacts/cli/__init__.py:
|
51
|
+
#: artefacts/cli/__init__.py:312
|
52
52
|
#, python-brace-format
|
53
53
|
msgid "Error uploading {file_name}: {error_message}, skipping"
|
54
54
|
msgstr ""
|
@@ -424,21 +424,22 @@ msgstr ""
|
|
424
424
|
msgid "Package run failed:"
|
425
425
|
msgstr ""
|
426
426
|
|
427
|
-
#: artefacts/cli/config.py:
|
427
|
+
#: artefacts/cli/config.py:47
|
428
428
|
#, python-brace-format
|
429
429
|
msgid "No API KEY set. Please run `artefacts config add {project_name}`"
|
430
430
|
msgstr ""
|
431
431
|
|
432
|
-
#: artefacts/cli/config.py:
|
432
|
+
#: artefacts/cli/config.py:66 artefacts/cli/config.py:74
|
433
433
|
#, python-brace-format
|
434
434
|
msgid "Connecting to {api_url} using {auth_type}"
|
435
435
|
msgstr ""
|
436
436
|
|
437
|
-
#: artefacts/cli/config.py:
|
437
|
+
#: artefacts/cli/config.py:103
|
438
438
|
msgid ""
|
439
|
-
"Unable to
|
440
|
-
"
|
441
|
-
"
|
439
|
+
"Unable to complete the operation: Network error.\n"
|
440
|
+
"This may be a problem with an Artefacts server, or your network.\n"
|
441
|
+
"Please try again in a moment or confirm your internet connection.\n"
|
442
|
+
"If the problem persists, please contact us (info@artefacts.com)!\n"
|
442
443
|
msgstr ""
|
443
444
|
|
444
445
|
#: artefacts/cli/ros1.py:55
|
@@ -6,9 +6,9 @@
|
|
6
6
|
#, fuzzy
|
7
7
|
msgid ""
|
8
8
|
msgstr ""
|
9
|
-
"Project-Id-Version: artefacts 0.9.
|
9
|
+
"Project-Id-Version: artefacts 0.9.5.dev7\n"
|
10
10
|
"Report-Msgid-Bugs-To: dev@artefacts.com\n"
|
11
|
-
"POT-Creation-Date: 2025-06-
|
11
|
+
"POT-Creation-Date: 2025-06-24 09:46+0900\n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
@@ -22,33 +22,33 @@ msgstr ""
|
|
22
22
|
msgid "Could not determine package version: {error_message}. Default to 0.0.0"
|
23
23
|
msgstr ""
|
24
24
|
|
25
|
-
#: artefacts/cli/__init__.py:
|
25
|
+
#: artefacts/cli/__init__.py:98
|
26
26
|
#, python-brace-format
|
27
27
|
msgid "Error on job creation: {status_code}"
|
28
28
|
msgstr ""
|
29
29
|
|
30
|
-
#: artefacts/cli/__init__.py:
|
30
|
+
#: artefacts/cli/__init__.py:172
|
31
31
|
#, python-brace-format
|
32
32
|
msgid "Error on scenario creation: {status_code}"
|
33
33
|
msgstr ""
|
34
34
|
|
35
|
-
#: artefacts/cli/__init__.py:
|
35
|
+
#: artefacts/cli/__init__.py:281
|
36
36
|
msgid ""
|
37
37
|
"Files generated by the job are not uploaded to Artefacts, including the ones "
|
38
38
|
"specified in output_dirs"
|
39
39
|
msgstr ""
|
40
40
|
|
41
|
-
#: artefacts/cli/__init__.py:
|
41
|
+
#: artefacts/cli/__init__.py:293
|
42
42
|
#, python-brace-format
|
43
43
|
msgid "Uploading {file_name} ({file_size:.2f} MB)"
|
44
44
|
msgstr ""
|
45
45
|
|
46
|
-
#: artefacts/cli/__init__.py:
|
46
|
+
#: artefacts/cli/__init__.py:304
|
47
47
|
#, python-brace-format
|
48
48
|
msgid "File too large: {file_name} could not be uploaded"
|
49
49
|
msgstr ""
|
50
50
|
|
51
|
-
#: artefacts/cli/__init__.py:
|
51
|
+
#: artefacts/cli/__init__.py:312
|
52
52
|
#, python-brace-format
|
53
53
|
msgid "Error uploading {file_name}: {error_message}, skipping"
|
54
54
|
msgstr ""
|
@@ -421,21 +421,22 @@ msgstr ""
|
|
421
421
|
msgid "Package run failed:"
|
422
422
|
msgstr ""
|
423
423
|
|
424
|
-
#: artefacts/cli/config.py:
|
424
|
+
#: artefacts/cli/config.py:47
|
425
425
|
#, python-brace-format
|
426
426
|
msgid "No API KEY set. Please run `artefacts config add {project_name}`"
|
427
427
|
msgstr ""
|
428
428
|
|
429
|
-
#: artefacts/cli/config.py:
|
429
|
+
#: artefacts/cli/config.py:66 artefacts/cli/config.py:74
|
430
430
|
#, python-brace-format
|
431
431
|
msgid "Connecting to {api_url} using {auth_type}"
|
432
432
|
msgstr ""
|
433
433
|
|
434
|
-
#: artefacts/cli/config.py:
|
434
|
+
#: artefacts/cli/config.py:103
|
435
435
|
msgid ""
|
436
|
-
"Unable to
|
437
|
-
"
|
438
|
-
"
|
436
|
+
"Unable to complete the operation: Network error.\n"
|
437
|
+
"This may be a problem with an Artefacts server, or your network.\n"
|
438
|
+
"Please try again in a moment or confirm your internet connection.\n"
|
439
|
+
"If the problem persists, please contact us (info@artefacts.com)!\n"
|
439
440
|
msgstr ""
|
440
441
|
|
441
442
|
#: artefacts/cli/ros1.py:55
|
@@ -6,9 +6,9 @@
|
|
6
6
|
#, fuzzy
|
7
7
|
msgid ""
|
8
8
|
msgstr ""
|
9
|
-
"Project-Id-Version: artefacts 0.9.
|
9
|
+
"Project-Id-Version: artefacts 0.9.5.dev7\n"
|
10
10
|
"Report-Msgid-Bugs-To: dev@artefacts.com\n"
|
11
|
-
"POT-Creation-Date: 2025-06-
|
11
|
+
"POT-Creation-Date: 2025-06-24 09:46+0900\n"
|
12
12
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
13
13
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
14
14
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
{artefacts_cli-0.9.4 → artefacts_cli-0.9.5}/artefacts/cli/locales/ja_JP/LC_MESSAGES/artefacts.po
RENAMED
@@ -7,7 +7,7 @@ msgid ""
|
|
7
7
|
msgstr ""
|
8
8
|
"Project-Id-Version: artefacts VERSION\n"
|
9
9
|
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
|
10
|
-
"POT-Creation-Date: 2025-06-
|
10
|
+
"POT-Creation-Date: 2025-06-24 09:46+0900\n"
|
11
11
|
"PO-Revision-Date: 2025-04-15 15:16+0900\n"
|
12
12
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
13
13
|
"Language: ja_JP\n"
|
@@ -23,33 +23,33 @@ msgstr ""
|
|
23
23
|
msgid "Could not determine package version: {error_message}. Default to 0.0.0"
|
24
24
|
msgstr "パッケージバージョン認識エラー:{error_message}. 0.0.0に設定して実行します"
|
25
25
|
|
26
|
-
#: artefacts/cli/__init__.py:
|
26
|
+
#: artefacts/cli/__init__.py:98
|
27
27
|
#, python-brace-format
|
28
28
|
msgid "Error on job creation: {status_code}"
|
29
29
|
msgstr "ジョブ作成エラー:{status_code}"
|
30
30
|
|
31
|
-
#: artefacts/cli/__init__.py:
|
31
|
+
#: artefacts/cli/__init__.py:172
|
32
32
|
#, python-brace-format
|
33
33
|
msgid "Error on scenario creation: {status_code}"
|
34
34
|
msgstr "シナリオ作成エラー:{status_code}"
|
35
35
|
|
36
|
-
#: artefacts/cli/__init__.py:
|
36
|
+
#: artefacts/cli/__init__.py:281
|
37
37
|
msgid ""
|
38
38
|
"Files generated by the job are not uploaded to Artefacts, including the "
|
39
39
|
"ones specified in output_dirs"
|
40
40
|
msgstr "ジョブによって生成されたファイルは、output_dirsで指定されたものも含め、Artefactsにアップロードされません"
|
41
41
|
|
42
|
-
#: artefacts/cli/__init__.py:
|
42
|
+
#: artefacts/cli/__init__.py:293
|
43
43
|
#, python-brace-format
|
44
44
|
msgid "Uploading {file_name} ({file_size:.2f} MB)"
|
45
45
|
msgstr "{file_name}をアップロード中({file_size:.2f} MB)"
|
46
46
|
|
47
|
-
#: artefacts/cli/__init__.py:
|
47
|
+
#: artefacts/cli/__init__.py:304
|
48
48
|
#, python-brace-format
|
49
49
|
msgid "File too large: {file_name} could not be uploaded"
|
50
50
|
msgstr "ファイルが大きすぎます:{file_name}をアップロードできませんでした"
|
51
51
|
|
52
|
-
#: artefacts/cli/__init__.py:
|
52
|
+
#: artefacts/cli/__init__.py:312
|
53
53
|
#, python-brace-format
|
54
54
|
msgid "Error uploading {file_name}: {error_message}, skipping"
|
55
55
|
msgstr "{file_name}のアップロードエラー:{error_message}、スキップします"
|
@@ -442,24 +442,27 @@ msgstr "コンテナ実行完了:検査用のコンテナID:{container_id}"
|
|
442
442
|
msgid "Package run failed:"
|
443
443
|
msgstr "パッケージ実行失敗:"
|
444
444
|
|
445
|
-
#: artefacts/cli/config.py:
|
445
|
+
#: artefacts/cli/config.py:47
|
446
446
|
#, python-brace-format
|
447
447
|
msgid "No API KEY set. Please run `artefacts config add {project_name}`"
|
448
448
|
msgstr "APIキーが設定されていません。`artefacts config add {project_name}`を実行してください"
|
449
449
|
|
450
|
-
#: artefacts/cli/config.py:
|
450
|
+
#: artefacts/cli/config.py:66 artefacts/cli/config.py:74
|
451
451
|
#, python-brace-format
|
452
452
|
msgid "Connecting to {api_url} using {auth_type}"
|
453
453
|
msgstr "{auth_type}を使用して{api_url}に接続中"
|
454
454
|
|
455
|
-
#: artefacts/cli/config.py:
|
455
|
+
#: artefacts/cli/config.py:103
|
456
456
|
msgid ""
|
457
|
-
"Unable to
|
458
|
-
"
|
459
|
-
"
|
457
|
+
"Unable to complete the operation: Network error.\n"
|
458
|
+
"This may be a problem with an Artefacts server, or your network.\n"
|
459
|
+
"Please try again in a moment or confirm your internet connection.\n"
|
460
|
+
"If the problem persists, please contact us (info@artefacts.com)!\n"
|
460
461
|
msgstr ""
|
461
|
-
"
|
462
|
-
"
|
462
|
+
"操作を完了できません:ネットワークエラー。\n"
|
463
|
+
"これはArtefactsサーバーまたはお客様のネットワークの問題である可能性があります。\n"
|
464
|
+
"しばらくしてから再度お試しいただくか、インターネット接続をご確認ください。\n"
|
465
|
+
"問題が解決しない場合は、お気軽にお問い合わせください(info@artefacts.com)!\n"
|
463
466
|
|
464
467
|
#: artefacts/cli/ros1.py:55
|
465
468
|
msgid ""
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: artefacts_cli
|
3
|
-
Version: 0.9.
|
3
|
+
Version: 0.9.5
|
4
4
|
Author-email: FD <fabian@artefacts.com>, AGC <alejandro@artefacts.com>, TN <tomo@artefacts.com>, EP <eric@artefacts.com>
|
5
5
|
License-Expression: Apache-2.0
|
6
6
|
Project-URL: Homepage, https://github.com/art-e-fact/artefacts-client
|
@@ -42,6 +42,9 @@ Requires-Dist: python-markdown-math; extra == "dev"
|
|
42
42
|
Requires-Dist: ruff>=0.9.2; extra == "dev"
|
43
43
|
Requires-Dist: setuptools_scm>=8; extra == "dev"
|
44
44
|
Requires-Dist: twine; extra == "dev"
|
45
|
+
Provides-Extra: dev-extended
|
46
|
+
Requires-Dist: artefacts_cli[dev]; extra == "dev-extended"
|
47
|
+
Requires-Dist: pytest-watch; extra == "dev-extended"
|
45
48
|
|
46
49
|
# Artefacts CLI
|
47
50
|
|
@@ -56,6 +56,7 @@ infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/src/turtle_trajectory.p
|
|
56
56
|
infra-tests/turtlesim1/ros_workspace/src/turtle_odometry/test/viz_turtle_odom.xml
|
57
57
|
infra-tests/turtlesim2/launch_turtle.py
|
58
58
|
infra-tests/turtlesim2/sample_node.py
|
59
|
+
scripts/whats_latest.rb
|
59
60
|
tests/__init__.py
|
60
61
|
tests/conftest.py
|
61
62
|
tests/cli/__init__.py
|
@@ -3,6 +3,7 @@
|
|
3
3
|
set -e
|
4
4
|
|
5
5
|
production=${1:-no}
|
6
|
+
version_override=${2:-no}
|
6
7
|
|
7
8
|
if [[ -d venv ]]
|
8
9
|
then
|
@@ -10,6 +11,10 @@ then
|
|
10
11
|
fi
|
11
12
|
|
12
13
|
# Get the new version
|
14
|
+
if [[ "$version_override" != "no" ]]
|
15
|
+
then
|
16
|
+
export SETUPTOOLS_SCM_PRETEND_VERSION=$version_override
|
17
|
+
fi
|
13
18
|
new_version=$(python -m setuptools_scm)
|
14
19
|
|
15
20
|
if [[ ! "$new_version" =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]+\.?\d?\e?\v?[0-9]?$ ]] && [[ "$production" != "production" ]]
|
@@ -68,6 +68,11 @@ dev = [
|
|
68
68
|
"twine",
|
69
69
|
]
|
70
70
|
|
71
|
+
dev-extended = [
|
72
|
+
"artefacts_cli[dev]",
|
73
|
+
"pytest-watch",
|
74
|
+
]
|
75
|
+
|
71
76
|
[project.urls]
|
72
77
|
"Homepage" = "https://github.com/art-e-fact/artefacts-client"
|
73
78
|
"Bug Tracker" = "https://github.com/art-e-fact/artefacts-client/issues"
|
@@ -0,0 +1,11 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
#
|
4
|
+
# Parse our CHANGELOG.md file to get the latest release "block"
|
5
|
+
# and prints it to stdout.
|
6
|
+
#
|
7
|
+
|
8
|
+
cl = open("CHANGELOG.md").read
|
9
|
+
start = cl.index /## \[Unreleased\]/
|
10
|
+
finish = cl.index /## \[\d\.\d+\.\d+\] - \d{4}-\d{2}-\d{2}/
|
11
|
+
print cl[start...finish].chomp
|
@@ -1,9 +1,16 @@
|
|
1
1
|
import pytest
|
2
2
|
from datetime import datetime, timezone
|
3
|
+
from uuid import uuid4
|
3
4
|
|
4
5
|
|
5
|
-
from artefacts.cli import
|
6
|
+
from artefacts.cli import (
|
7
|
+
ArtefactsAPIError,
|
8
|
+
AuthenticationError,
|
9
|
+
generate_scenarios,
|
10
|
+
WarpJob,
|
11
|
+
)
|
6
12
|
from artefacts.cli.app import run
|
13
|
+
from artefacts.cli.config import APIConf
|
7
14
|
|
8
15
|
|
9
16
|
def test_generate_scenarios(loaded_valid_conf):
|
@@ -119,15 +126,142 @@ def test_default_params_overwritten_by_launch_argument(loaded_valid_conf):
|
|
119
126
|
}
|
120
127
|
|
121
128
|
|
122
|
-
def
|
129
|
+
def test_job_empty_init_dryrun():
|
123
130
|
"""
|
124
|
-
Plain basic test the WarpJob object initialises as expected.
|
131
|
+
Plain basic test the WarpJob object initialises as expected on dryrun.
|
125
132
|
"""
|
126
133
|
job = WarpJob("project", {}, "jobname", {}, dryrun=True)
|
127
134
|
assert job.success is False
|
128
135
|
assert job.start < datetime.now(timezone.utc).timestamp()
|
129
136
|
|
130
137
|
|
138
|
+
def test_job_empty_init(mocker, valid_project_settings):
|
139
|
+
"""
|
140
|
+
Plain basic test the WarpJob object initialises as expected.
|
141
|
+
"""
|
142
|
+
success = mocker.Mock()
|
143
|
+
success.status_code = 200
|
144
|
+
success.json.return_value = {"job_id": str(uuid4())}
|
145
|
+
test_session = mocker.Mock()
|
146
|
+
test_session.post.return_value = success
|
147
|
+
job = WarpJob(
|
148
|
+
"project",
|
149
|
+
APIConf(
|
150
|
+
valid_project_settings["full_project_name"],
|
151
|
+
"test_version",
|
152
|
+
session=test_session,
|
153
|
+
),
|
154
|
+
"jobname",
|
155
|
+
{},
|
156
|
+
)
|
157
|
+
assert job.success is False
|
158
|
+
assert job.start < datetime.now(timezone.utc).timestamp()
|
159
|
+
|
160
|
+
|
161
|
+
def test_job_update(mocker, valid_project_settings):
|
162
|
+
"""
|
163
|
+
Test on the update function of WarpJob objects.
|
164
|
+
"""
|
165
|
+
success = mocker.Mock()
|
166
|
+
success.status_code = 200
|
167
|
+
success.json.return_value = {"job_id": str(uuid4())}
|
168
|
+
test_session = mocker.Mock()
|
169
|
+
test_session.post.return_value = success
|
170
|
+
test_session.put.return_value = success
|
171
|
+
job = WarpJob(
|
172
|
+
"project",
|
173
|
+
APIConf(
|
174
|
+
valid_project_settings["full_project_name"],
|
175
|
+
"test_version",
|
176
|
+
session=test_session,
|
177
|
+
),
|
178
|
+
"jobname",
|
179
|
+
{},
|
180
|
+
)
|
181
|
+
assert job.update(True)
|
182
|
+
|
183
|
+
|
184
|
+
def test_job_valid_context(mocker, valid_project_settings):
|
185
|
+
"""
|
186
|
+
Check that a custom context param is processed as expected.
|
187
|
+
|
188
|
+
A job creation currently invokes the API at init time,
|
189
|
+
which is supposed to send any optional `context` data.
|
190
|
+
"""
|
191
|
+
now = datetime.now()
|
192
|
+
time_mock = mocker.patch("datetime.datetime")
|
193
|
+
time_mock.now.return_value = now
|
194
|
+
success = mocker.Mock()
|
195
|
+
success.status_code = 200
|
196
|
+
success.json.return_value = {"job_id": str(uuid4())}
|
197
|
+
api_conf = mocker.Mock()
|
198
|
+
api_conf.create = mocker.Mock(return_value=success)
|
199
|
+
WarpJob(
|
200
|
+
"project",
|
201
|
+
api_conf,
|
202
|
+
"jobname",
|
203
|
+
{},
|
204
|
+
context={
|
205
|
+
"description": "test",
|
206
|
+
"commit": "testcommithash",
|
207
|
+
"ref": "testref",
|
208
|
+
},
|
209
|
+
)
|
210
|
+
api_conf.create.assert_called_with(
|
211
|
+
"job",
|
212
|
+
dict(
|
213
|
+
project_id="project",
|
214
|
+
start=round(now.timestamp()),
|
215
|
+
status="in progress",
|
216
|
+
params="{}",
|
217
|
+
project="project",
|
218
|
+
jobname="jobname",
|
219
|
+
timeout=300,
|
220
|
+
n_subjobs=1,
|
221
|
+
message="test",
|
222
|
+
commit="testcommithash",
|
223
|
+
ref="testref",
|
224
|
+
),
|
225
|
+
)
|
226
|
+
|
227
|
+
|
228
|
+
def test_job_creation_403(mocker):
|
229
|
+
"""
|
230
|
+
Check bad authentication is handled.
|
231
|
+
"""
|
232
|
+
error403 = mocker.Mock()
|
233
|
+
error403.status_code = 403
|
234
|
+
error403.json.return_value = {"message": "bad auth"}
|
235
|
+
api_conf = mocker.Mock()
|
236
|
+
api_conf.create = mocker.Mock(return_value=error403)
|
237
|
+
with pytest.raises(AuthenticationError) as error:
|
238
|
+
WarpJob(
|
239
|
+
"project",
|
240
|
+
api_conf,
|
241
|
+
"jobname",
|
242
|
+
{},
|
243
|
+
)
|
244
|
+
assert "bad auth" in str(error)
|
245
|
+
|
246
|
+
|
247
|
+
def test_job_creation_non_403_error(mocker):
|
248
|
+
"""
|
249
|
+
Check non-403 errors are handled.
|
250
|
+
"""
|
251
|
+
error401 = mocker.Mock()
|
252
|
+
error401.status_code = 401
|
253
|
+
api_conf = mocker.Mock()
|
254
|
+
api_conf.create = mocker.Mock(return_value=error401)
|
255
|
+
with pytest.raises(ArtefactsAPIError) as error:
|
256
|
+
WarpJob(
|
257
|
+
"project",
|
258
|
+
api_conf,
|
259
|
+
"jobname",
|
260
|
+
{},
|
261
|
+
)
|
262
|
+
assert "401" in str(error)
|
263
|
+
|
264
|
+
|
131
265
|
@pytest.mark.ros2
|
132
266
|
def test_job_update_called_after_every_run(
|
133
267
|
cli_runner, authorised_project_with_conf, mocker
|
@@ -1,8 +1,10 @@
|
|
1
|
+
import pytest
|
2
|
+
|
1
3
|
import json
|
2
4
|
|
3
5
|
from requests import Response
|
4
6
|
|
5
|
-
from artefacts.cli import WarpRun
|
7
|
+
from artefacts.cli import ArtefactsAPIError, AuthenticationError, WarpJob, WarpRun
|
6
8
|
|
7
9
|
|
8
10
|
def test_run_with_upload_on_stop(mocker, artefacts_run):
|
@@ -137,3 +139,62 @@ def test_run_uses_scenario_name_on_stop_for_all_parameterised_runs(
|
|
137
139
|
run.stop()
|
138
140
|
assert "scenario_name" in spy.call_args.args[2]
|
139
141
|
assert expected_name == spy.call_args.args[2]["scenario_name"]
|
142
|
+
|
143
|
+
|
144
|
+
def test_run_creation_403(mocker):
|
145
|
+
"""
|
146
|
+
Check bad authentication is handled.
|
147
|
+
"""
|
148
|
+
success = mocker.Mock()
|
149
|
+
success.status_code = 200
|
150
|
+
success.json.return_value = {"job_id": "test"}
|
151
|
+
error403 = mocker.Mock()
|
152
|
+
error403.status_code = 403
|
153
|
+
error403.json.return_value = {"message": "bad auth"}
|
154
|
+
|
155
|
+
def behaviour(obj, data):
|
156
|
+
if "job" == obj:
|
157
|
+
return success
|
158
|
+
elif "run" == obj:
|
159
|
+
return error403
|
160
|
+
|
161
|
+
api_conf = mocker.Mock()
|
162
|
+
api_conf.create = mocker.Mock(side_effect=behaviour)
|
163
|
+
job = WarpJob(
|
164
|
+
"project",
|
165
|
+
api_conf,
|
166
|
+
"jobname",
|
167
|
+
{},
|
168
|
+
)
|
169
|
+
with pytest.raises(AuthenticationError) as error:
|
170
|
+
WarpRun(job=job, name="run", params={}, run_n=1)
|
171
|
+
assert "bad auth" in str(error)
|
172
|
+
|
173
|
+
|
174
|
+
def test_run_creation_non_403_error(mocker):
|
175
|
+
"""
|
176
|
+
Check non-403 errors are handled.
|
177
|
+
"""
|
178
|
+
success = mocker.Mock()
|
179
|
+
success.status_code = 200
|
180
|
+
success.json.return_value = {"job_id": "test"}
|
181
|
+
error401 = mocker.Mock()
|
182
|
+
error401.status_code = 401
|
183
|
+
|
184
|
+
def behaviour(obj, data):
|
185
|
+
if "job" == obj:
|
186
|
+
return success
|
187
|
+
elif "run" == obj:
|
188
|
+
return error401
|
189
|
+
|
190
|
+
api_conf = mocker.Mock()
|
191
|
+
api_conf.create = mocker.Mock(side_effect=behaviour)
|
192
|
+
job = WarpJob(
|
193
|
+
"project",
|
194
|
+
api_conf,
|
195
|
+
"jobname",
|
196
|
+
{},
|
197
|
+
)
|
198
|
+
with pytest.raises(ArtefactsAPIError) as error:
|
199
|
+
WarpRun(job=job, name="run", params={}, run_n=1)
|
200
|
+
assert "401" in str(error)
|
@@ -154,10 +154,19 @@ def sample_artefacts_config():
|
|
154
154
|
|
155
155
|
|
156
156
|
@pytest.fixture(scope="function")
|
157
|
-
def
|
157
|
+
def test_session(mocker):
|
158
|
+
return mocker.Mock()
|
159
|
+
|
160
|
+
|
161
|
+
@pytest.fixture(scope="function")
|
162
|
+
def artefacts_job(valid_project_settings, test_session):
|
158
163
|
return WarpJob(
|
159
164
|
valid_project_settings["full_project_name"],
|
160
|
-
APIConf(
|
165
|
+
APIConf(
|
166
|
+
valid_project_settings["full_project_name"],
|
167
|
+
"test_version",
|
168
|
+
session=test_session,
|
169
|
+
),
|
161
170
|
"jobname",
|
162
171
|
{},
|
163
172
|
dryrun=True,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|