dagster-evidence 0.1.6__py3-none-any.whl → 0.2.0__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.
- dagster_evidence/__init__.py +19 -2
- dagster_evidence/components/__init__.py +17 -0
- dagster_evidence/components/deployments.py +514 -0
- dagster_evidence/components/evidence_project_v2.py +185 -0
- dagster_evidence/components/projects.py +660 -0
- dagster_evidence/components/sources.py +1350 -0
- dagster_evidence/components/translator.py +168 -0
- dagster_evidence/lib/evidence_project.py +6 -5
- dagster_evidence/resource.py +4 -4
- dagster_evidence/utils/__init__.py +5 -0
- dagster_evidence/utils/sql_parser.py +87 -0
- dagster_evidence-0.2.0.dist-info/METADATA +120 -0
- dagster_evidence-0.2.0.dist-info/RECORD +17 -0
- {dagster_evidence-0.1.6.dist-info → dagster_evidence-0.2.0.dist-info}/WHEEL +1 -1
- dagster_evidence-0.1.6.dist-info/METADATA +0 -23
- dagster_evidence-0.1.6.dist-info/RECORD +0 -9
- {dagster_evidence-0.1.6.dist-info → dagster_evidence-0.2.0.dist-info}/entry_points.txt +0 -0
- {dagster_evidence-0.1.6.dist-info → dagster_evidence-0.2.0.dist-info}/top_level.txt +0 -0
dagster_evidence/__init__.py
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
from dagster._core.libraries import DagsterLibraryRegistry
|
|
2
2
|
|
|
3
|
+
from dagster_evidence.components.evidence_project_v2 import EvidenceProjectComponentV2
|
|
4
|
+
from dagster_evidence.components.sources import (
|
|
5
|
+
EvidenceProjectTranslatorData,
|
|
6
|
+
EvidenceSourceTranslatorData,
|
|
7
|
+
ProjectDagsterMetadata,
|
|
8
|
+
SourceDagsterMetadata,
|
|
9
|
+
)
|
|
10
|
+
from dagster_evidence.components.translator import DagsterEvidenceTranslator
|
|
3
11
|
from dagster_evidence.lib.evidence_project import EvidenceProject
|
|
4
12
|
from dagster_evidence.resource import EvidenceResource
|
|
5
13
|
|
|
6
|
-
__version__ = "0.
|
|
14
|
+
__version__ = "0.2.0"
|
|
7
15
|
|
|
8
|
-
__all__ = [
|
|
16
|
+
__all__ = [
|
|
17
|
+
"EvidenceProjectComponentV2",
|
|
18
|
+
"EvidenceProject",
|
|
19
|
+
"EvidenceResource",
|
|
20
|
+
"DagsterEvidenceTranslator",
|
|
21
|
+
"EvidenceSourceTranslatorData",
|
|
22
|
+
"EvidenceProjectTranslatorData",
|
|
23
|
+
"ProjectDagsterMetadata",
|
|
24
|
+
"SourceDagsterMetadata",
|
|
25
|
+
]
|
|
9
26
|
|
|
10
27
|
DagsterLibraryRegistry.register(
|
|
11
28
|
"dagster-evidence", __version__, is_dagster_package=False
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from dagster_evidence.components.evidence_project_v2 import (
|
|
2
|
+
EvidenceProjectComponentV2 as EvidenceProjectComponentV2,
|
|
3
|
+
)
|
|
4
|
+
from dagster_evidence.components.sources import (
|
|
5
|
+
EvidenceProjectTranslatorData as EvidenceProjectTranslatorData,
|
|
6
|
+
EvidenceSourceTranslatorData as EvidenceSourceTranslatorData,
|
|
7
|
+
)
|
|
8
|
+
from dagster_evidence.components.translator import (
|
|
9
|
+
DagsterEvidenceTranslator as DagsterEvidenceTranslator,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
__all__ = [
|
|
13
|
+
"EvidenceProjectComponentV2",
|
|
14
|
+
"DagsterEvidenceTranslator",
|
|
15
|
+
"EvidenceSourceTranslatorData",
|
|
16
|
+
"EvidenceProjectTranslatorData",
|
|
17
|
+
]
|
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
"""Deployment classes for Evidence projects.
|
|
2
|
+
|
|
3
|
+
This module provides deployment targets for Evidence projects, including
|
|
4
|
+
GitHub Pages, Netlify, and custom deployment commands.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import os
|
|
8
|
+
from abc import abstractmethod
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from typing import Literal, Optional
|
|
11
|
+
|
|
12
|
+
import dagster as dg
|
|
13
|
+
import yaml
|
|
14
|
+
from dagster._annotations import beta, public
|
|
15
|
+
from dagster.components.resolved.base import resolve_fields
|
|
16
|
+
from pydantic import BaseModel, Field
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@beta
|
|
20
|
+
@public
|
|
21
|
+
class BaseEvidenceProjectDeployment(dg.ConfigurableResource):
|
|
22
|
+
"""Base class for Evidence project deployment configurations.
|
|
23
|
+
|
|
24
|
+
Subclass this to implement custom deployment targets.
|
|
25
|
+
|
|
26
|
+
Example:
|
|
27
|
+
|
|
28
|
+
Implementing a custom S3 deployment:
|
|
29
|
+
|
|
30
|
+
.. code-block:: python
|
|
31
|
+
|
|
32
|
+
from dagster_evidence.components.deployments import (
|
|
33
|
+
BaseEvidenceProjectDeployment,
|
|
34
|
+
)
|
|
35
|
+
import dagster as dg
|
|
36
|
+
|
|
37
|
+
class S3EvidenceProjectDeployment(BaseEvidenceProjectDeployment):
|
|
38
|
+
s3_bucket: str
|
|
39
|
+
s3_prefix: str = ""
|
|
40
|
+
|
|
41
|
+
def deploy_evidence_project(
|
|
42
|
+
self,
|
|
43
|
+
evidence_project_build_path: str,
|
|
44
|
+
context: dg.AssetExecutionContext,
|
|
45
|
+
pipes_subprocess_client: dg.PipesSubprocessClient,
|
|
46
|
+
env: dict[str, str] | None = None,
|
|
47
|
+
) -> None:
|
|
48
|
+
context.log.info(
|
|
49
|
+
f"Deploying to s3://{self.s3_bucket}/{self.s3_prefix}"
|
|
50
|
+
)
|
|
51
|
+
import os
|
|
52
|
+
pipes_subprocess_client.run(
|
|
53
|
+
command=[
|
|
54
|
+
"aws", "s3", "sync",
|
|
55
|
+
evidence_project_build_path,
|
|
56
|
+
f"s3://{self.s3_bucket}/{self.s3_prefix}",
|
|
57
|
+
],
|
|
58
|
+
cwd=evidence_project_build_path,
|
|
59
|
+
context=context,
|
|
60
|
+
env=env or os.environ.copy(),
|
|
61
|
+
)
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
@public
|
|
65
|
+
@abstractmethod
|
|
66
|
+
def deploy_evidence_project(
|
|
67
|
+
self,
|
|
68
|
+
evidence_project_build_path: str,
|
|
69
|
+
context: dg.AssetExecutionContext,
|
|
70
|
+
pipes_subprocess_client: dg.PipesSubprocessClient,
|
|
71
|
+
env: Optional[dict[str, str]] = None,
|
|
72
|
+
) -> None:
|
|
73
|
+
"""Deploy the built Evidence project to the target destination.
|
|
74
|
+
|
|
75
|
+
Args:
|
|
76
|
+
evidence_project_build_path: Path to the built Evidence project output.
|
|
77
|
+
context: The Dagster asset execution context.
|
|
78
|
+
pipes_subprocess_client: Client for running subprocess commands.
|
|
79
|
+
env: Optional environment variables for the deployment process.
|
|
80
|
+
"""
|
|
81
|
+
raise NotImplementedError()
|
|
82
|
+
|
|
83
|
+
@public
|
|
84
|
+
def get_base_path(self, project_path: str) -> str:
|
|
85
|
+
"""Get the build output path for this deployment.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
project_path: Path to the Evidence project directory.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
The build output path. Default is 'build'.
|
|
92
|
+
"""
|
|
93
|
+
return "build"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@beta
|
|
97
|
+
@public
|
|
98
|
+
class CustomEvidenceProjectDeployment(BaseEvidenceProjectDeployment):
|
|
99
|
+
"""Custom deployment using a shell command.
|
|
100
|
+
|
|
101
|
+
Use this deployment type when you need to run a custom deployment script
|
|
102
|
+
or command that is not covered by the built-in deployment types.
|
|
103
|
+
|
|
104
|
+
Attributes:
|
|
105
|
+
deploy_command: The shell command to run for deployment.
|
|
106
|
+
|
|
107
|
+
Example:
|
|
108
|
+
|
|
109
|
+
.. code-block:: yaml
|
|
110
|
+
|
|
111
|
+
project_deployment:
|
|
112
|
+
type: custom
|
|
113
|
+
deploy_command: "rsync -avz ./ user@server:/var/www/dashboard/"
|
|
114
|
+
|
|
115
|
+
Or using a deployment script:
|
|
116
|
+
|
|
117
|
+
.. code-block:: yaml
|
|
118
|
+
|
|
119
|
+
project_deployment:
|
|
120
|
+
type: custom
|
|
121
|
+
deploy_command: "./deploy.sh production"
|
|
122
|
+
"""
|
|
123
|
+
|
|
124
|
+
deploy_command: str
|
|
125
|
+
|
|
126
|
+
def deploy_evidence_project(
|
|
127
|
+
self,
|
|
128
|
+
evidence_project_build_path: str,
|
|
129
|
+
context: dg.AssetExecutionContext,
|
|
130
|
+
pipes_subprocess_client: dg.PipesSubprocessClient,
|
|
131
|
+
env: Optional[dict[str, str]] = None,
|
|
132
|
+
) -> None:
|
|
133
|
+
if self.deploy_command is not None:
|
|
134
|
+
context.log.info(f"Running deploy command: {self.deploy_command}")
|
|
135
|
+
pipes_subprocess_client.run(
|
|
136
|
+
command=self.deploy_command,
|
|
137
|
+
cwd=evidence_project_build_path,
|
|
138
|
+
context=context,
|
|
139
|
+
env=env or os.environ.copy(),
|
|
140
|
+
)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
@beta
|
|
144
|
+
@public
|
|
145
|
+
class CustomEvidenceProjectDeploymentArgs(dg.Model, dg.Resolvable):
|
|
146
|
+
"""Arguments for configuring a custom deployment command.
|
|
147
|
+
|
|
148
|
+
Example:
|
|
149
|
+
|
|
150
|
+
.. code-block:: yaml
|
|
151
|
+
|
|
152
|
+
project_deployment:
|
|
153
|
+
type: custom
|
|
154
|
+
deploy_command: "aws s3 sync build/ s3://my-bucket/dashboard/"
|
|
155
|
+
|
|
156
|
+
Attributes:
|
|
157
|
+
type: Must be "custom" to use this deployment type.
|
|
158
|
+
deploy_command: Shell command to execute for deployment.
|
|
159
|
+
"""
|
|
160
|
+
|
|
161
|
+
type: Literal["custom"] = Field(
|
|
162
|
+
default="custom",
|
|
163
|
+
description="Deployment type identifier.",
|
|
164
|
+
)
|
|
165
|
+
deploy_command: str = Field(
|
|
166
|
+
...,
|
|
167
|
+
description="Custom command to run for deployment.",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
@beta
|
|
172
|
+
@public
|
|
173
|
+
class GithubPagesEvidenceProjectDeployment(BaseEvidenceProjectDeployment):
|
|
174
|
+
"""Deploy Evidence project to GitHub Pages.
|
|
175
|
+
|
|
176
|
+
This deployment type pushes the built Evidence project to a GitHub Pages
|
|
177
|
+
branch, enabling automatic hosting via GitHub.
|
|
178
|
+
|
|
179
|
+
Requirements:
|
|
180
|
+
- evidence.config.yaml must have deployment.basePath configured
|
|
181
|
+
- A GitHub token with repo write access
|
|
182
|
+
|
|
183
|
+
Attributes:
|
|
184
|
+
github_repo: Repository in "owner/repo" format.
|
|
185
|
+
branch: Target branch for deployment (default: "gh-pages").
|
|
186
|
+
github_token: GitHub token for authentication.
|
|
187
|
+
|
|
188
|
+
Example:
|
|
189
|
+
|
|
190
|
+
.. code-block:: yaml
|
|
191
|
+
|
|
192
|
+
project_deployment:
|
|
193
|
+
type: github_pages
|
|
194
|
+
github_repo: my-org/analytics-dashboard
|
|
195
|
+
branch: gh-pages
|
|
196
|
+
github_token: ${GITHUB_TOKEN}
|
|
197
|
+
|
|
198
|
+
Your evidence.config.yaml should include:
|
|
199
|
+
|
|
200
|
+
.. code-block:: yaml
|
|
201
|
+
|
|
202
|
+
deployment:
|
|
203
|
+
basePath: /analytics-dashboard
|
|
204
|
+
"""
|
|
205
|
+
|
|
206
|
+
github_repo: str # e.g., "milicevica23/food-tracking-serving"
|
|
207
|
+
branch: str = "gh-pages"
|
|
208
|
+
github_token: str # Token resolved at component load time (from config or GITHUB_TOKEN env var)
|
|
209
|
+
|
|
210
|
+
def get_base_path(self, project_path: str) -> str:
|
|
211
|
+
"""Get the build output path from evidence.config.yaml for GitHub Pages.
|
|
212
|
+
|
|
213
|
+
Args:
|
|
214
|
+
project_path: Path to the Evidence project directory.
|
|
215
|
+
|
|
216
|
+
Returns:
|
|
217
|
+
The build path in format 'build/{basePath}'.
|
|
218
|
+
|
|
219
|
+
Raises:
|
|
220
|
+
FileNotFoundError: If evidence.config.yaml is not found.
|
|
221
|
+
ValueError: If basePath is not configured in deployment section.
|
|
222
|
+
"""
|
|
223
|
+
config_path = Path(project_path) / "evidence.config.yaml"
|
|
224
|
+
if not config_path.exists():
|
|
225
|
+
raise FileNotFoundError(
|
|
226
|
+
f"evidence.config.yaml not found at {config_path}. "
|
|
227
|
+
"See: https://docs.evidence.dev/deployment/self-host/github-pages/"
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
with open(config_path, "r") as f:
|
|
231
|
+
config = yaml.safe_load(f)
|
|
232
|
+
|
|
233
|
+
deployment_config = config.get("deployment", {})
|
|
234
|
+
if not deployment_config:
|
|
235
|
+
raise ValueError(
|
|
236
|
+
"Missing 'deployment' section in evidence.config.yaml. "
|
|
237
|
+
"GitHub Pages deployment requires 'deployment.basePath' to be configured. "
|
|
238
|
+
"See: https://docs.evidence.dev/deployment/self-host/github-pages/"
|
|
239
|
+
)
|
|
240
|
+
|
|
241
|
+
base_path = deployment_config.get("basePath")
|
|
242
|
+
if not base_path:
|
|
243
|
+
raise ValueError(
|
|
244
|
+
"Missing 'basePath' in deployment section of evidence.config.yaml. "
|
|
245
|
+
"GitHub Pages deployment requires 'deployment.basePath' to be configured. "
|
|
246
|
+
"See: https://docs.evidence.dev/deployment/self-host/github-pages/"
|
|
247
|
+
)
|
|
248
|
+
|
|
249
|
+
# Remove leading slash and prepend with build/
|
|
250
|
+
return f"build/{base_path.lstrip('/')}"
|
|
251
|
+
|
|
252
|
+
def deploy_evidence_project(
|
|
253
|
+
self,
|
|
254
|
+
evidence_project_build_path: str,
|
|
255
|
+
context: dg.AssetExecutionContext,
|
|
256
|
+
pipes_subprocess_client: dg.PipesSubprocessClient,
|
|
257
|
+
env: Optional[dict[str, str]] = None,
|
|
258
|
+
) -> None:
|
|
259
|
+
"""Deploy Evidence project build to GitHub Pages using GitPython."""
|
|
260
|
+
from datetime import datetime, timezone
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
from git import Repo
|
|
264
|
+
except ImportError:
|
|
265
|
+
raise ImportError(
|
|
266
|
+
"GitPython is required for GitHub Pages deployment. "
|
|
267
|
+
"Install it with: pip install dagster-evidence[github-pages]"
|
|
268
|
+
) from None
|
|
269
|
+
|
|
270
|
+
if not os.path.isdir(evidence_project_build_path):
|
|
271
|
+
raise FileNotFoundError(
|
|
272
|
+
f"Build directory not found: {evidence_project_build_path}"
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
context.log.info("Deploying to GitHub Pages...")
|
|
276
|
+
context.log.info(f" Repo: {self.github_repo}")
|
|
277
|
+
context.log.info(f" Branch: {self.branch}")
|
|
278
|
+
context.log.info(f" Build path: {evidence_project_build_path}")
|
|
279
|
+
|
|
280
|
+
# Initialize git repo directly in the build directory
|
|
281
|
+
repo = Repo.init(evidence_project_build_path, initial_branch="main")
|
|
282
|
+
|
|
283
|
+
# Add remote with token auth (token is never logged)
|
|
284
|
+
remote_url = f"https://x-access-token:{self.github_token}@github.com/{self.github_repo}.git"
|
|
285
|
+
origin = repo.create_remote("origin", remote_url)
|
|
286
|
+
|
|
287
|
+
# Disable Jekyll processing (required for files/folders starting with _)
|
|
288
|
+
Path(evidence_project_build_path, ".nojekyll").touch()
|
|
289
|
+
|
|
290
|
+
# Configure git user
|
|
291
|
+
repo.config_writer().set_value(
|
|
292
|
+
"user", "name", "Dagster Evidence Deploy"
|
|
293
|
+
).release()
|
|
294
|
+
repo.config_writer().set_value("user", "email", "dagster@localhost").release()
|
|
295
|
+
|
|
296
|
+
# Add all files
|
|
297
|
+
repo.index.add("*")
|
|
298
|
+
repo.index.add(".nojekyll")
|
|
299
|
+
|
|
300
|
+
# Commit
|
|
301
|
+
timestamp = datetime.now(timezone.utc).strftime("%Y-%m-%d_%H:%M:%S")
|
|
302
|
+
repo.index.commit(f"Deploy Evidence dashboard {timestamp}")
|
|
303
|
+
|
|
304
|
+
# Create and checkout branch
|
|
305
|
+
new_branch = repo.create_head(self.branch)
|
|
306
|
+
new_branch.checkout()
|
|
307
|
+
|
|
308
|
+
# Force push
|
|
309
|
+
origin.push(refspec=f"{self.branch}:{self.branch}", force=True)
|
|
310
|
+
|
|
311
|
+
context.log.info("Deployment complete!")
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
@beta
|
|
315
|
+
@public
|
|
316
|
+
class GithubPagesEvidenceProjectDeploymentArgs(dg.Model, dg.Resolvable):
|
|
317
|
+
"""Arguments for deploying Evidence project to GitHub Pages.
|
|
318
|
+
|
|
319
|
+
Example:
|
|
320
|
+
|
|
321
|
+
.. code-block:: yaml
|
|
322
|
+
|
|
323
|
+
project_deployment:
|
|
324
|
+
type: github_pages
|
|
325
|
+
github_repo: owner/repo-name
|
|
326
|
+
branch: gh-pages
|
|
327
|
+
|
|
328
|
+
With explicit token (not recommended - prefer env var):
|
|
329
|
+
|
|
330
|
+
.. code-block:: yaml
|
|
331
|
+
|
|
332
|
+
project_deployment:
|
|
333
|
+
type: github_pages
|
|
334
|
+
github_repo: owner/repo-name
|
|
335
|
+
github_token: ghp_xxxxxxxxxxxx
|
|
336
|
+
|
|
337
|
+
Attributes:
|
|
338
|
+
type: Must be "github_pages" to use this deployment type.
|
|
339
|
+
github_repo: Repository in "owner/repo" format.
|
|
340
|
+
branch: Target branch (default: "gh-pages").
|
|
341
|
+
github_token: GitHub token. Falls back to GITHUB_TOKEN env var if not provided.
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
type: Literal["github_pages"] = Field(
|
|
345
|
+
default="github_pages",
|
|
346
|
+
description="Deployment type identifier.",
|
|
347
|
+
)
|
|
348
|
+
github_repo: str = Field(
|
|
349
|
+
...,
|
|
350
|
+
description="GitHub repository in format 'owner/repo' (e.g., 'milicevica23/my-dashboard').",
|
|
351
|
+
)
|
|
352
|
+
branch: str = Field(
|
|
353
|
+
default="gh-pages",
|
|
354
|
+
description="Branch to deploy to (default: gh-pages).",
|
|
355
|
+
)
|
|
356
|
+
github_token: Optional[str] = Field(
|
|
357
|
+
default=None,
|
|
358
|
+
description="GitHub token for authentication. If not provided, falls back to GITHUB_TOKEN env var.",
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
@beta
|
|
363
|
+
@public
|
|
364
|
+
class EvidenceProjectNetlifyDeployment(BaseEvidenceProjectDeployment):
|
|
365
|
+
"""Deploy Evidence project to Netlify.
|
|
366
|
+
|
|
367
|
+
**Coming Soon** - This deployment type is planned but not yet implemented.
|
|
368
|
+
|
|
369
|
+
This deployment type will push the built Evidence project to Netlify,
|
|
370
|
+
enabling automatic hosting and CDN distribution.
|
|
371
|
+
|
|
372
|
+
Planned Features:
|
|
373
|
+
- Deploy via Netlify CLI or API
|
|
374
|
+
- Support for deploy previews
|
|
375
|
+
- Environment variable configuration
|
|
376
|
+
- Build hooks integration
|
|
377
|
+
|
|
378
|
+
Attributes:
|
|
379
|
+
netlify_project_url: URL of the Netlify project.
|
|
380
|
+
|
|
381
|
+
Example:
|
|
382
|
+
|
|
383
|
+
.. code-block:: yaml
|
|
384
|
+
|
|
385
|
+
project_deployment:
|
|
386
|
+
type: netlify
|
|
387
|
+
netlify_project_url: https://app.netlify.com/sites/my-dashboard
|
|
388
|
+
netlify_auth_token: ${NETLIFY_AUTH_TOKEN}
|
|
389
|
+
|
|
390
|
+
Note:
|
|
391
|
+
If you need Netlify deployment support, please open an issue on GitHub
|
|
392
|
+
to help prioritize this feature. In the meantime, you can use the
|
|
393
|
+
``custom`` deployment type with the Netlify CLI.
|
|
394
|
+
"""
|
|
395
|
+
|
|
396
|
+
netlify_project_url: str
|
|
397
|
+
|
|
398
|
+
def deploy_evidence_project(
|
|
399
|
+
self,
|
|
400
|
+
evidence_project_build_path: str,
|
|
401
|
+
context: dg.AssetExecutionContext,
|
|
402
|
+
pipes_subprocess_client: dg.PipesSubprocessClient,
|
|
403
|
+
env: Optional[dict[str, str]] = None,
|
|
404
|
+
) -> None:
|
|
405
|
+
raise NotImplementedError()
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
@beta
|
|
409
|
+
@public
|
|
410
|
+
class EvidenceProjectNetlifyDeploymentArgs(dg.Model, dg.Resolvable):
|
|
411
|
+
"""Arguments for deploying Evidence project to Netlify.
|
|
412
|
+
|
|
413
|
+
**Coming Soon** - This deployment type is planned but not yet implemented.
|
|
414
|
+
|
|
415
|
+
Example:
|
|
416
|
+
|
|
417
|
+
.. code-block:: yaml
|
|
418
|
+
|
|
419
|
+
project_deployment:
|
|
420
|
+
type: netlify
|
|
421
|
+
netlify_project_url: https://app.netlify.com/sites/my-dashboard
|
|
422
|
+
|
|
423
|
+
Attributes:
|
|
424
|
+
type: Must be "netlify" to use this deployment type.
|
|
425
|
+
netlify_project_url: URL of the Netlify project.
|
|
426
|
+
|
|
427
|
+
Note:
|
|
428
|
+
Use the ``custom`` deployment type with Netlify CLI as a workaround:
|
|
429
|
+
|
|
430
|
+
.. code-block:: yaml
|
|
431
|
+
|
|
432
|
+
project_deployment:
|
|
433
|
+
type: custom
|
|
434
|
+
deploy_command: "netlify deploy --prod --dir=."
|
|
435
|
+
"""
|
|
436
|
+
|
|
437
|
+
type: Literal["netlify"] = Field(
|
|
438
|
+
default="netlify",
|
|
439
|
+
description="Deployment type identifier.",
|
|
440
|
+
)
|
|
441
|
+
netlify_project_url: str = Field(
|
|
442
|
+
...,
|
|
443
|
+
description="Netlify project URL.",
|
|
444
|
+
)
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
@public
|
|
448
|
+
def resolve_evidence_project_deployment(
|
|
449
|
+
context: dg.ResolutionContext, model: BaseModel
|
|
450
|
+
) -> BaseEvidenceProjectDeployment:
|
|
451
|
+
"""Resolve deployment configuration to a concrete deployment instance.
|
|
452
|
+
|
|
453
|
+
This function is used internally by the component resolution system
|
|
454
|
+
to convert YAML configuration into deployment instances.
|
|
455
|
+
|
|
456
|
+
Args:
|
|
457
|
+
context: The resolution context.
|
|
458
|
+
model: The parsed configuration model.
|
|
459
|
+
|
|
460
|
+
Returns:
|
|
461
|
+
A BaseEvidenceProjectDeployment instance.
|
|
462
|
+
|
|
463
|
+
Raises:
|
|
464
|
+
NotImplementedError: If an unknown deployment type is specified.
|
|
465
|
+
ValueError: If required configuration is missing (e.g., github_token).
|
|
466
|
+
"""
|
|
467
|
+
# First, check which type we're dealing with
|
|
468
|
+
deployment_type = (
|
|
469
|
+
model.get("type", "custom")
|
|
470
|
+
if isinstance(model, dict)
|
|
471
|
+
else getattr(model, "type", "custom")
|
|
472
|
+
)
|
|
473
|
+
|
|
474
|
+
if deployment_type == "github_pages":
|
|
475
|
+
resolved = resolve_fields(
|
|
476
|
+
model=model,
|
|
477
|
+
resolved_cls=GithubPagesEvidenceProjectDeploymentArgs,
|
|
478
|
+
context=context,
|
|
479
|
+
)
|
|
480
|
+
# Resolve token: use provided value or fall back to env var
|
|
481
|
+
github_token = resolved.get("github_token") or os.environ.get("GITHUB_TOKEN")
|
|
482
|
+
if not github_token:
|
|
483
|
+
raise ValueError(
|
|
484
|
+
"GitHub token is required for github_pages deployment. "
|
|
485
|
+
"Provide 'github_token' in config or set GITHUB_TOKEN environment variable."
|
|
486
|
+
)
|
|
487
|
+
return GithubPagesEvidenceProjectDeployment(
|
|
488
|
+
github_repo=resolved["github_repo"],
|
|
489
|
+
branch=resolved.get(
|
|
490
|
+
"branch",
|
|
491
|
+
GithubPagesEvidenceProjectDeploymentArgs.model_fields["branch"].default,
|
|
492
|
+
),
|
|
493
|
+
github_token=github_token,
|
|
494
|
+
)
|
|
495
|
+
elif deployment_type == "netlify":
|
|
496
|
+
resolved = resolve_fields(
|
|
497
|
+
model=model,
|
|
498
|
+
resolved_cls=EvidenceProjectNetlifyDeploymentArgs,
|
|
499
|
+
context=context,
|
|
500
|
+
)
|
|
501
|
+
return EvidenceProjectNetlifyDeployment(
|
|
502
|
+
netlify_project_url=resolved["netlify_project_url"],
|
|
503
|
+
)
|
|
504
|
+
elif deployment_type == "custom":
|
|
505
|
+
resolved = resolve_fields(
|
|
506
|
+
model=model,
|
|
507
|
+
resolved_cls=CustomEvidenceProjectDeploymentArgs,
|
|
508
|
+
context=context,
|
|
509
|
+
)
|
|
510
|
+
return CustomEvidenceProjectDeployment(
|
|
511
|
+
deploy_command=resolved["deploy_command"],
|
|
512
|
+
)
|
|
513
|
+
else:
|
|
514
|
+
raise NotImplementedError(f"Unknown deployment type: {deployment_type}")
|