ultralytics-actions 0.0.36__tar.gz → 0.0.38__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.
Files changed (22) hide show
  1. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/PKG-INFO +2 -2
  2. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/README.md +1 -1
  3. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/__init__.py +1 -1
  4. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/utils/common_utils.py +11 -6
  5. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/pyproject.toml +4 -0
  6. ultralytics_actions-0.0.38/tests/test_urls.py +99 -0
  7. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/PKG-INFO +2 -2
  8. ultralytics_actions-0.0.36/tests/test_urls.py +0 -15
  9. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/LICENSE +0 -0
  10. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/first_interaction.py +0 -0
  11. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/summarize_pr.py +0 -0
  12. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/summarize_release.py +0 -0
  13. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/update_markdown_code_blocks.py +0 -0
  14. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/utils/__init__.py +0 -0
  15. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/utils/github_utils.py +0 -0
  16. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/actions/utils/openai_utils.py +0 -0
  17. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/setup.cfg +0 -0
  18. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/SOURCES.txt +0 -0
  19. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/dependency_links.txt +0 -0
  20. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/entry_points.txt +0 -0
  21. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/requires.txt +0 -0
  22. {ultralytics_actions-0.0.36 → ultralytics_actions-0.0.38}/ultralytics_actions.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics-actions
3
- Version: 0.0.36
3
+ Version: 0.0.38
4
4
  Summary: Ultralytics Actions for GitHub automation and PR management.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -99,7 +99,7 @@ To use this action in your Ultralytics repository:
99
99
  labels: true # autolabel issues and PRs
100
100
  python: true # format Python code and docstrings
101
101
  prettier: true # format YAML, JSON, Markdown and CSS
102
- swift: true # format Swift code (requires 'macos-latest')
102
+ swift: true # format Swift code (requires 'macos-latest' runner)
103
103
  spelling: true # check spelling
104
104
  links: true # check broken links
105
105
  summary: true # print PR summary with GPT4o (requires 'openai_api_key')
@@ -63,7 +63,7 @@ To use this action in your Ultralytics repository:
63
63
  labels: true # autolabel issues and PRs
64
64
  python: true # format Python code and docstrings
65
65
  prettier: true # format YAML, JSON, Markdown and CSS
66
- swift: true # format Swift code (requires 'macos-latest')
66
+ swift: true # format Swift code (requires 'macos-latest' runner)
67
67
  spelling: true # check spelling
68
68
  links: true # check broken links
69
69
  summary: true # print PR summary with GPT4o (requires 'openai_api_key')
@@ -22,4 +22,4 @@
22
22
  # ├── test_summarize_pr.py
23
23
  # └── ...
24
24
 
25
- __version__ = "0.0.36"
25
+ __version__ = "0.0.38"
@@ -50,7 +50,8 @@ def is_url(url, check=True, max_attempts=3, timeout=2):
50
50
 
51
51
  # Check structure
52
52
  result = parse.urlparse(url)
53
- if not all([result.scheme, result.netloc]):
53
+ partition = result.netloc.partition(".") # i.e. netloc = "github.com" -> ("github", ".", "com")
54
+ if not result.scheme or not partition[0] or not partition[2]:
54
55
  return False
55
56
 
56
57
  # Check response
@@ -58,10 +59,10 @@ def is_url(url, check=True, max_attempts=3, timeout=2):
58
59
  for attempt in range(max_attempts):
59
60
  try:
60
61
  headers = {
61
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/120.0.0.0",
62
- "Accept": "*",
63
- "Accept-Language": "*",
64
- "Accept-Encoding": "*",
62
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
63
+ "Accept": "*/*", # Wildcard for maximum compatibility
64
+ "Accept-Language": "*", # Wildcard for any language
65
+ "Accept-Encoding": "*", # Wildcard for any encoding
65
66
  }
66
67
  return requests.head(url, headers=headers, timeout=timeout, allow_redirects=True).status_code < 400
67
68
  except Exception:
@@ -82,7 +83,7 @@ def check_links_in_string(text, verbose=True, return_bad=False):
82
83
  r"(" # Start capturing group for plaintext URLs
83
84
  r"(?:https?://)?" # Optional http:// or https://
84
85
  r"(?:www\.)?" # Optional www.
85
- r"[\w.-]+" # Domain name and subdomains
86
+ r"(?:[\w.-]+)?" # Optional domain name and subdomains
86
87
  r"\.[a-zA-Z]{2,}" # TLD
87
88
  r"(?:/[^\s\"')\]]*)?" # Optional path
88
89
  r")"
@@ -104,3 +105,7 @@ def check_links_in_string(text, verbose=True, return_bad=False):
104
105
  print(f"WARNING ⚠️ errors found in URLs {bad_urls}")
105
106
 
106
107
  return (passing, bad_urls) if return_bad else passing
108
+
109
+
110
+ if __name__ == "__main__":
111
+ print(is_url("https://ultralytics.com/images/bus.jpg"))
@@ -95,6 +95,10 @@ packages = { find = { where = ["."], include = ["actions", "actions.*"] } }
95
95
  [tool.setuptools.dynamic]
96
96
  version = { attr = "actions.__version__" }
97
97
 
98
+ [tool.pytest.ini_options]
99
+ addopts = "--doctest-modules --durations=30 --color=yes"
100
+ norecursedirs = [".git", "dist", "build"]
101
+
98
102
  [tool.ruff]
99
103
  line-length = 120
100
104
 
@@ -0,0 +1,99 @@
1
+ # Ultralytics Actions 🚀, AGPL-3.0 license
2
+ # Continuous Integration (CI) GitHub Actions tests
3
+
4
+ import pytest
5
+
6
+ from actions.utils.common_utils import check_links_in_string, is_url
7
+
8
+ URLS = [
9
+ "https://docs.ultralytics.com/help/CLA/",
10
+ "https://docs.ultralytics.com/help/contributing",
11
+ "https://docs.ultralytics.com",
12
+ "https://ultralytics.com",
13
+ "https://ultralytics.com/images/bus.jpg",
14
+ "https://github.com/ultralytics/ultralytics",
15
+ ]
16
+
17
+
18
+ @pytest.fixture
19
+ def verbose():
20
+ """Fixture that provides a verbose logging utility for detailed output during testing and debugging."""
21
+ return False # Set False to suppress print statements during tests
22
+
23
+
24
+ def test_is_url():
25
+ """Test each URL using is_url function."""
26
+ for url in URLS:
27
+ assert is_url(url), f"URL check failed: {url}"
28
+
29
+
30
+ def test_html_links(verbose):
31
+ """Tests the validity of URLs within HTML anchor tags and returns any invalid URLs found."""
32
+ text = "Visit <a href='https://err.com'>our site</a> or <a href=\"http://test.org\">test site</a>"
33
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
34
+ assert result is False
35
+ assert set(urls) == {"https://err.com", "http://test.org"}
36
+
37
+
38
+ def test_markdown_links(verbose):
39
+ """Validates URLs in markdown links within a given text using check_links_in_string."""
40
+ text = "Check [Example](https://err.com) or [Test](http://test.org)"
41
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
42
+ assert result is False
43
+ assert set(urls) == {"https://err.com", "http://test.org"}
44
+
45
+
46
+ def test_mixed_formats(verbose):
47
+ """Tests URL detection in mixed text formats (HTML, Markdown, plain text) using check_links_in_string."""
48
+ text = "A <a href='https://1.com'>link</a> and [markdown](https://2.org) and https://3.net"
49
+ result, urls = check_links_in_string(text, return_bad=True)
50
+ assert result is False
51
+ assert set(urls) == {"https://1.com", "https://2.org", "https://3.net"}
52
+
53
+
54
+ def test_duplicate_urls(verbose):
55
+ """Tests detection of duplicate URLs in various text formats using the check_links_in_string function."""
56
+ text = "Same URL: https://err.com and <a href='https://err.com'>link</a>"
57
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
58
+ assert result is False
59
+ assert set(urls) == {"https://err.com"}
60
+
61
+
62
+ def test_no_urls(verbose):
63
+ """Tests that a string with no URLs returns True when checked using the check_links_in_string function."""
64
+ text = "This text contains no URLs."
65
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
66
+ assert result is True
67
+ assert not set(urls)
68
+
69
+
70
+ def test_invalid_urls(verbose):
71
+ """Test invalid URLs."""
72
+ text = "Invalid URL: http://.com"
73
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
74
+ assert result is False
75
+ assert set(urls) == {"http://.com"}
76
+
77
+
78
+ def test_urls_with_paths_and_queries(verbose):
79
+ """Test URLs with paths and query parameters to ensure they are correctly identified and validated."""
80
+ text = "Complex URL: https://err.com/path?query=value#fragment"
81
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
82
+ assert result is False
83
+ assert set(urls) == {"https://err.com/path?query=value#fragment"}
84
+
85
+
86
+ def test_urls_with_different_tlds(verbose):
87
+ """Test URLs with various top-level domains (TLDs) to ensure correct identification and handling."""
88
+ text = "Different TLDs: https://err.ml https://err.org https://err.net https://err.io https://err.ai"
89
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
90
+ assert result is False
91
+ assert set(urls) == {"https://err.ml", "https://err.org", "https://err.net", "https://err.io", "https://err.ai"}
92
+
93
+
94
+ def test_case_sensitivity(verbose):
95
+ """Tests URL case sensitivity by verifying that URLs with different cases are correctly identified and handled."""
96
+ text = "Case test: HTTPS://err.com and https://err.com"
97
+ result, urls = check_links_in_string(text, verbose, return_bad=True)
98
+ assert result is False
99
+ assert set(urls) == {"https://err.com"}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: ultralytics-actions
3
- Version: 0.0.36
3
+ Version: 0.0.38
4
4
  Summary: Ultralytics Actions for GitHub automation and PR management.
5
5
  Author-email: Glenn Jocher <glenn.jocher@ultralytics.com>
6
6
  Maintainer-email: Ultralytics <hello@ultralytics.com>
@@ -99,7 +99,7 @@ To use this action in your Ultralytics repository:
99
99
  labels: true # autolabel issues and PRs
100
100
  python: true # format Python code and docstrings
101
101
  prettier: true # format YAML, JSON, Markdown and CSS
102
- swift: true # format Swift code (requires 'macos-latest')
102
+ swift: true # format Swift code (requires 'macos-latest' runner)
103
103
  spelling: true # check spelling
104
104
  links: true # check broken links
105
105
  summary: true # print PR summary with GPT4o (requires 'openai_api_key')
@@ -1,15 +0,0 @@
1
- from actions.utils.common_utils import is_url
2
-
3
- URLS = [
4
- "https://docs.ultralytics.com/help/CLA/",
5
- "https://docs.ultralytics.com/help/contributing",
6
- "https://docs.ultralytics.com",
7
- "https://ultralytics.com",
8
- "https://github.com/ultralytics/ultralytics",
9
- ]
10
-
11
-
12
- def test_urls():
13
- """Test each URL using is_url function."""
14
- for url in URLS:
15
- assert is_url(url), f"URL check failed: {url}"