-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat: Extract and send tooling versions to Sentry (EME-606) #464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 7 commits
f12c060
47a4a6a
5998900
4b10d48
0cfd711
8bb5f86
0a59a68
acb6caa
3b2c2d5
76cdd8e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -459,6 +459,9 @@ def _get_artifact_type(artifact: Artifact) -> ArtifactType: | |
| apple_app_info=apple_app_info, | ||
| android_app_info=android_app_info, | ||
| dequeued_at=dequeued_at, | ||
| cli_version=app_info.cli_version, | ||
| fastlane_plugin_version=app_info.fastlane_plugin_version, | ||
|
||
| gradle_plugin_version=app_info.gradle_plugin_version, | ||
| ) | ||
|
|
||
| return update_data.model_dump(exclude_none=True) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| """Utility for extracting metadata from .sentry-cli-metadata.txt files in artifacts.""" | ||
|
|
||
| import zipfile | ||
|
|
||
| from pathlib import Path | ||
| from typing import Dict, Optional | ||
|
|
||
| from launchpad.utils.logging import get_logger | ||
|
|
||
| logger = get_logger(__name__) | ||
|
|
||
| METADATA_FILENAME = ".sentry-cli-metadata.txt" | ||
|
|
||
|
|
||
| class ToolingMetadata: | ||
| """Container for tooling version metadata extracted from artifacts.""" | ||
runningcode marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def __init__( | ||
| self, | ||
| cli_version: Optional[str] = None, | ||
| fastlane_plugin_version: Optional[str] = None, | ||
| gradle_plugin_version: Optional[str] = None, | ||
| ): | ||
| self.cli_version = cli_version | ||
| self.fastlane_plugin_version = fastlane_plugin_version | ||
| self.gradle_plugin_version = gradle_plugin_version | ||
|
|
||
| def __repr__(self) -> str: | ||
runningcode marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return f"ToolingMetadata(cli_version={self.cli_version}, fastlane_plugin_version={self.fastlane_plugin_version}, gradle_plugin_version={self.gradle_plugin_version})" | ||
|
|
||
|
|
||
| def extract_metadata_from_zip(zip_path: Path) -> ToolingMetadata: | ||
| """Extract tooling metadata from a .sentry-cli-metadata.txt file in the root of a zip. | ||
runningcode marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Args: | ||
| zip_path: Path to the zip file to search | ||
| Returns: | ||
| ToolingMetadata object with extracted version information | ||
| """ | ||
| try: | ||
| with zipfile.ZipFile(zip_path, "r") as zf: | ||
| # Only look for .sentry-cli-metadata.txt in the root of the zip | ||
| if METADATA_FILENAME not in zf.namelist(): | ||
| logger.debug(f"No {METADATA_FILENAME} found in root of {zip_path}") | ||
| return ToolingMetadata() | ||
|
|
||
| logger.debug(f"Found metadata file: {METADATA_FILENAME}") | ||
|
|
||
| with zf.open(METADATA_FILENAME) as f: | ||
| content = f.read().decode("utf-8") | ||
| return _parse_metadata_content(content) | ||
|
|
||
| except Exception as e: | ||
| logger.warning(f"Failed to extract metadata from {zip_path}: {e}") | ||
| return ToolingMetadata() | ||
|
|
||
|
|
||
| def _parse_metadata_content(content: str) -> ToolingMetadata: | ||
| """Parse the content of .sentry-cli-metadata.txt file. | ||
| Expected format: | ||
| sentry-cli-version: 2.58.2 | ||
| sentry-fastlane-plugin: 1.2.3 | ||
| sentry-gradle-plugin: 4.12.0 | ||
| Args: | ||
runningcode marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| content: The text content of the metadata file | ||
| Returns: | ||
| ToolingMetadata object with parsed version information | ||
| """ | ||
| metadata: Dict[str, str] = {} | ||
|
|
||
| for line in content.strip().split("\n"): | ||
| line = line.strip() | ||
| if not line or ":" not in line: | ||
| continue | ||
|
|
||
| key, value = line.split(":", 1) | ||
| key = key.strip() | ||
| value = value.strip() | ||
|
|
||
| metadata[key] = value | ||
|
|
||
| return ToolingMetadata( | ||
| cli_version=metadata.get("sentry-cli-version"), | ||
| fastlane_plugin_version=metadata.get("sentry-fastlane-plugin"), | ||
| gradle_plugin_version=metadata.get("sentry-gradle-plugin"), | ||
| ) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| """Tests for metadata extraction from .sentry-cli-metadata.txt files.""" | ||
|
|
||
| import tempfile | ||
| import zipfile | ||
|
|
||
| from pathlib import Path | ||
|
|
||
| from launchpad.utils.metadata_extractor import ( | ||
| ToolingMetadata, | ||
| _parse_metadata_content, | ||
| extract_metadata_from_zip, | ||
| ) | ||
|
|
||
|
|
||
| class TestParseMetadataContent: | ||
| """Tests for parsing .sentry-cli-metadata.txt content.""" | ||
runningcode marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| def test_parse_all_fields(self): | ||
| content = """sentry-cli-version: 2.58.2 | ||
| sentry-fastlane-plugin: 1.2.3 | ||
| sentry-gradle-plugin: 4.12.0""" | ||
| metadata = _parse_metadata_content(content) | ||
| assert metadata.cli_version == "2.58.2" | ||
| assert metadata.fastlane_plugin_version == "1.2.3" | ||
| assert metadata.gradle_plugin_version == "4.12.0" | ||
|
|
||
| def test_parse_empty_content(self): | ||
| content = "" | ||
| metadata = _parse_metadata_content(content) | ||
| assert metadata.cli_version is None | ||
| assert metadata.fastlane_plugin_version is None | ||
| assert metadata.gradle_plugin_version is None | ||
|
|
||
|
|
||
| class TestExtractMetadataFromZip: | ||
| """Tests for extracting metadata from zip files.""" | ||
|
|
||
| def test_extract_from_zip_root(self): | ||
| with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as tf: | ||
| try: | ||
| with zipfile.ZipFile(tf.name, "w") as zf: | ||
| zf.writestr( | ||
| ".sentry-cli-metadata.txt", | ||
| "sentry-cli-version: 2.58.2\nsentry-fastlane-plugin: 1.2.3\nsentry-gradle-plugin: 4.12.0", | ||
| ) | ||
| zf.writestr("some-file.txt", "content") | ||
|
|
||
| metadata = extract_metadata_from_zip(Path(tf.name)) | ||
| assert metadata.cli_version == "2.58.2" | ||
| assert metadata.fastlane_plugin_version == "1.2.3" | ||
| assert metadata.gradle_plugin_version == "4.12.0" | ||
| finally: | ||
| Path(tf.name).unlink() | ||
|
|
||
| def test_extract_when_missing(self): | ||
| with tempfile.NamedTemporaryFile(suffix=".zip", delete=False) as tf: | ||
| try: | ||
| with zipfile.ZipFile(tf.name, "w") as zf: | ||
| zf.writestr("some-file.txt", "content") | ||
| zf.writestr("other-file.txt", "content") | ||
|
|
||
| metadata = extract_metadata_from_zip(Path(tf.name)) | ||
| assert metadata.cli_version is None | ||
| assert metadata.fastlane_plugin_version is None | ||
| assert metadata.gradle_plugin_version is None | ||
| finally: | ||
| Path(tf.name).unlink() | ||
|
|
||
|
|
||
| class TestToolingMetadata: | ||
| """Tests for ToolingMetadata container class.""" | ||
|
|
||
| def test_create_with_defaults(self): | ||
| metadata = ToolingMetadata() | ||
| assert metadata.cli_version is None | ||
| assert metadata.fastlane_plugin_version is None | ||
| assert metadata.gradle_plugin_version is None | ||
Uh oh!
There was an error while loading. Please reload this page.