github-local 0.0.1b3763__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 (23) hide show
  1. github_local-0.0.1b3763/.coveragerc +6 -0
  2. github_local-0.0.1b3763/.flake8 +3 -0
  3. github_local-0.0.1b3763/PKG-INFO +23 -0
  4. github_local-0.0.1b3763/README.md +5 -0
  5. github_local-0.0.1b3763/pyproject.toml +35 -0
  6. github_local-0.0.1b3763/pytest.ini +5 -0
  7. github_local-0.0.1b3763/python_packages/conftest.py +8 -0
  8. github_local-0.0.1b3763/python_packages/github_local/__init__.py +0 -0
  9. github_local-0.0.1b3763/python_packages/github_local/src/__init__.py +0 -0
  10. github_local-0.0.1b3763/python_packages/github_local/src/constants_github_local.py +6 -0
  11. github_local-0.0.1b3763/python_packages/github_local/src/github_local.py +91 -0
  12. github_local-0.0.1b3763/python_packages/github_local/tests/__init__.py +0 -0
  13. github_local-0.0.1b3763/python_packages/github_local/tests/unit/__init__.py +0 -0
  14. github_local-0.0.1b3763/python_packages/github_local/tests/unit/conftest.py +66 -0
  15. github_local-0.0.1b3763/python_packages/github_local/tests/unit/github_local_unit_test.py +118 -0
  16. github_local-0.0.1b3763/python_packages/github_local.egg-info/PKG-INFO +23 -0
  17. github_local-0.0.1b3763/python_packages/github_local.egg-info/SOURCES.txt +21 -0
  18. github_local-0.0.1b3763/python_packages/github_local.egg-info/dependency_links.txt +1 -0
  19. github_local-0.0.1b3763/python_packages/github_local.egg-info/requires.txt +2 -0
  20. github_local-0.0.1b3763/python_packages/github_local.egg-info/top_level.txt +1 -0
  21. github_local-0.0.1b3763/requirements.txt +3 -0
  22. github_local-0.0.1b3763/setup.cfg +4 -0
  23. github_local-0.0.1b3763/setup.py +95 -0
@@ -0,0 +1,6 @@
1
+ # The publish workflow runs pytest with --cov=. , so measure only the source code (as pytest.ini does)
2
+ [run]
3
+ omit =
4
+ setup.py
5
+ */conftest.py
6
+ */tests/*
@@ -0,0 +1,3 @@
1
+ [flake8]
2
+ exclude = lib/
3
+ max-line-length = 120
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: github-local
3
+ Version: 0.0.1b3763
4
+ Summary: PyPI github-local Python Package owned by Circlez.ai
5
+ Home-page: https://github.com/circles-zone/github-local-python-package
6
+ Author: Circles
7
+ Author-email: info@circlez.ai
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: python-sdk-remote
12
+ Requires-Dist: requests
13
+ Dynamic: author
14
+ Dynamic: author-email
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: home-page
19
+ Dynamic: requires-dist
20
+ Dynamic: summary
21
+
22
+ PyPI github-local Python Package owned by Circlez.ai
23
+ GHA: https://github.com/circles-zone/github-local-python-package/actions
@@ -0,0 +1,5 @@
1
+ # github-local
2
+
3
+ Base Python package for the GitHub REST API of the circles-zone organization: which Jira Work Items (by key, e.g. BU-1234) were merged to dev, and the branches of a Jira Work Item with the age of their last commit.
4
+
5
+ Environment variable: `GITHUB_TOKEN` (read access to the repos' contents and pull requests).
@@ -0,0 +1,35 @@
1
+ # This file should be in the future instead of setup.py
2
+ # https://python-poetry.org/docs/pyproject
3
+ # https://stackoverflow.com/questions/78048223/adding-folder-with-data-with-pyproject-toml
4
+ # https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license
5
+
6
+ # This file is mandatory for the `poetry version patch`
7
+
8
+ # It seems we need to copy this file also to serverless-com repo, as required by dialog-workflow-python-package
9
+
10
+ [build-system]
11
+ # "setuptools_scm>=6.2" is required for writing the version in my_package/_version.py and may be also for "poetry version patch" to work
12
+ requires = ["setuptools>=61.0", "setuptools_scm>=6.2"]
13
+ build-backend = "setuptools.build_meta"
14
+
15
+ [tool.setuptools_scm]
16
+ write_to = "python_packages/github_local/_version.py"
17
+
18
+ [tool.pytest.ini_options]
19
+ pythonpath = ["."]
20
+
21
+ [tool.poetry]
22
+ # TODO: Please update the name, similar to storage-local (suffix -local)
23
+ name = "github-local"
24
+ # TODO After the b (beta), you should add the Jira Work Item ID (was generated by Jira). If you run sdk-local Makec.ps1 it should do it for you.
25
+ # I believe we are still using the version from setup.py and not from here until Potery will work
26
+ version = "0.0.1b3763" # https://pypi.org/project/github-local/
27
+ description = "github-local Python Package"
28
+ readme = "README.md"
29
+ authors = [
30
+ "Circlez.ai <info@circlez.ai>",
31
+ ]
32
+
33
+ [tool.poetry.dev-dependencies]
34
+ pytest = "^8.0"
35
+ pytest-cov = "^5.0"
@@ -0,0 +1,5 @@
1
+ [pytest]
2
+ addopts = --maxfail=1 --cov=python_packages/github_local/src --cov-branch --cov-report=term-missing --cov-fail-under=100
3
+ testpaths = python_packages
4
+ pythonpath = python_packages
5
+ python_files = *_test.py
@@ -0,0 +1,8 @@
1
+ from dotenv import load_dotenv
2
+ from python_sdk_remote.utilities import our_get_env, our_set_env
3
+
4
+ load_dotenv()
5
+
6
+ for key, default_value in {"BRAND_NAME": "Circlez", "ENVIRONMENT_NAME": "play1"}.items():
7
+ if not our_get_env(key, raise_if_not_found=False):
8
+ our_set_env(key, default_value)
@@ -0,0 +1,6 @@
1
+ GITHUB_TOKEN_ENV = "GITHUB_TOKEN"
2
+ GITHUB_ORGANIZATION = "circles-zone"
3
+ GITHUB_API_URL = "https://api.github.com"
4
+ GITHUB_MAX_KEYS_PER_SEARCH = 5 # GitHub search allows up to 5 OR operators
5
+ GITHUB_SEARCH_MAX_PAGES = 10 # GitHub search returns at most 1000 results (10 pages of 100)
6
+ GITHUB_REQUEST_TIMEOUT_SECONDS = 10
@@ -0,0 +1,91 @@
1
+ import re
2
+ from datetime import datetime, timezone
3
+ from typing import Any, Optional
4
+
5
+ import requests
6
+ from python_sdk_remote.utilities import our_get_env
7
+
8
+ from .constants_github_local import (
9
+ GITHUB_API_URL,
10
+ GITHUB_MAX_KEYS_PER_SEARCH,
11
+ GITHUB_ORGANIZATION,
12
+ GITHUB_REQUEST_TIMEOUT_SECONDS,
13
+ GITHUB_SEARCH_MAX_PAGES,
14
+ GITHUB_TOKEN_ENV,
15
+ )
16
+
17
+ WORK_ITEM_KEY_PATTERN = re.compile(r"\b[A-Z][A-Z0-9]+-\d+\b")
18
+ GITHUB_PAGE_SIZE = 100
19
+
20
+
21
+ class GitHubLocalException(Exception):
22
+ pass
23
+
24
+
25
+ def is_branch_of_key(branch_name: str, key: str) -> bool:
26
+ """feature/BU-1-x and BU-1 belong to BU-1, feature/BU-10-x does not."""
27
+ is_branch_of_key_result = re.fullmatch(rf"(feature/)?{re.escape(key)}([^0-9].*)?", branch_name,
28
+ re.IGNORECASE) is not None
29
+ return is_branch_of_key_result
30
+
31
+
32
+ class GitHubLocal:
33
+ """Which Jira Work Items were merged to dev, and the branches of a Jira Work Item."""
34
+
35
+ def __init__(self, token: Optional[str] = None, organization: str = GITHUB_ORGANIZATION) -> None:
36
+ self.organization = organization
37
+ github_token = token or our_get_env(GITHUB_TOKEN_ENV, raise_if_empty=True)
38
+ self.session = requests.Session()
39
+ self.session.headers.update({"Accept": "application/vnd.github+json",
40
+ "Authorization": f"Bearer {github_token}"})
41
+
42
+ def get_keys_merged_to_dev(self, keys: list[str]) -> set[str]:
43
+ """PR title = branch name = feature/BU-1234-..., so a merged PR to dev with the key in its title
44
+ means the Jira Work Item was merged."""
45
+ merged_keys: set[str] = set()
46
+ for start in range(0, len(keys), GITHUB_MAX_KEYS_PER_SEARCH):
47
+ batch = keys[start:start + GITHUB_MAX_KEYS_PER_SEARCH]
48
+ query = f"org:{self.organization} is:pr is:merged base:dev in:title " + " OR ".join(batch)
49
+ for page in range(1, GITHUB_SEARCH_MAX_PAGES + 1):
50
+ search_result = self._get("/search/issues", params={"q": query, "per_page": GITHUB_PAGE_SIZE,
51
+ "page": page})
52
+ pull_requests = search_result.get("items") or []
53
+ for pull_request in pull_requests:
54
+ merged_keys.update(key for key in WORK_ITEM_KEY_PATTERN.findall(
55
+ str(pull_request.get("title", "")).upper()) if key in batch)
56
+ if len(pull_requests) < GITHUB_PAGE_SIZE:
57
+ break
58
+ return merged_keys
59
+
60
+ def get_branches(self, repo_name: str, key: str) -> list[dict[str, Any]]:
61
+ """Branches named feature/<key>... or <key>... (exactly this key) with the age of their last commit."""
62
+ branches = []
63
+ for prefix in (f"feature/{key}", key):
64
+ refs = self._get(f"/repos/{self.organization}/{repo_name}/git/matching-refs/heads/{prefix}",
65
+ is_not_found_empty=True)
66
+ for ref in refs:
67
+ branch_name = ref["ref"].removeprefix("refs/heads/")
68
+ if not is_branch_of_key(branch_name, key):
69
+ continue
70
+ commit = self._get(f"/repos/{self.organization}/{repo_name}/commits/{ref['object']['sha']}")
71
+ last_commit_time = datetime.fromisoformat(commit["commit"]["committer"]["date"].replace("Z", "+00:00"))
72
+ branches.append({"repo_name": repo_name, "branch_name": branch_name,
73
+ "age": datetime.now(timezone.utc) - last_commit_time})
74
+ return branches
75
+
76
+ def _get(self, path: str, params: Optional[dict[str, Any]] = None, is_not_found_empty: bool = False) -> Any:
77
+ try:
78
+ response = self.session.get(f"{GITHUB_API_URL}{path}", params=params,
79
+ timeout=GITHUB_REQUEST_TIMEOUT_SECONDS)
80
+ except requests.RequestException as exception:
81
+ raise GitHubLocalException(f"GitHub is unreachable: {exception}")
82
+ if response.status_code == 404 and is_not_found_empty:
83
+ response_json: Any = []
84
+ elif not response.ok:
85
+ raise GitHubLocalException(f"GitHub GET {path} failed with {response.status_code}: {response.text[:200]}")
86
+ else:
87
+ try:
88
+ response_json = response.json()
89
+ except ValueError:
90
+ raise GitHubLocalException(f"GitHub GET {path} returned an invalid response: {response.text[:200]}")
91
+ return response_json
@@ -0,0 +1,66 @@
1
+ import json as json_module
2
+ from dataclasses import dataclass
3
+ from typing import Any, Optional, Union
4
+
5
+ import pytest
6
+ import requests
7
+
8
+
9
+ @dataclass
10
+ class FakeHttpCall:
11
+ method: str
12
+ url: str
13
+ params: Optional[dict[str, Any]]
14
+ json: Optional[dict[str, Any]]
15
+
16
+
17
+ class FakeHttp:
18
+ """Answers requests.Session.request with the responses registered per method and URL, in order
19
+ (the last one repeats), and records every call. A request without a registered response fails the test."""
20
+
21
+ def __init__(self) -> None:
22
+ self.calls: list[FakeHttpCall] = []
23
+ self.responses_by_request: dict[tuple[str, str], list[Union[requests.Response, Exception]]] = {}
24
+
25
+ def add(self, method: str, url: str, status: int = 200, json: Any = None,
26
+ body: Union[str, Exception] = "") -> None:
27
+ if isinstance(body, Exception):
28
+ response: Union[requests.Response, Exception] = body
29
+ else:
30
+ response = requests.Response()
31
+ response.status_code = status
32
+ response.url = url
33
+ response._content = (body if json is None else json_module.dumps(json)).encode()
34
+ self.responses_by_request.setdefault((method, url), []).append(response)
35
+
36
+ def get(self, url: str, **kwargs: Any) -> None:
37
+ self.add("GET", url, **kwargs)
38
+
39
+ def post(self, url: str, **kwargs: Any) -> None:
40
+ self.add("POST", url, **kwargs)
41
+
42
+ def delete(self, url: str, **kwargs: Any) -> None:
43
+ self.add("DELETE", url, **kwargs)
44
+
45
+ def request(self, method: str, url: str, params: Optional[dict[str, Any]] = None,
46
+ json: Optional[dict[str, Any]] = None, **kwargs: Any) -> requests.Response:
47
+ self.calls.append(FakeHttpCall(method=method, url=url, params=params, json=json))
48
+ registered_responses = self.responses_by_request.get((method, url))
49
+ assert registered_responses, f"Unexpected HTTP request {method} {url}"
50
+ response = registered_responses.pop(0) if len(registered_responses) > 1 else registered_responses[0]
51
+ if isinstance(response, Exception):
52
+ raise response
53
+ return response
54
+
55
+
56
+ @pytest.fixture(autouse=True)
57
+ def fake_http(monkeypatch) -> FakeHttp:
58
+ """Unit tests never reach GitHub: every requests.Session request is answered by FakeHttp."""
59
+ fake_http = FakeHttp()
60
+
61
+ def session_request(session: requests.Session, method: str, url: str, **kwargs: Any) -> requests.Response:
62
+ response = fake_http.request(method, url, **kwargs)
63
+ return response
64
+
65
+ monkeypatch.setattr(requests.Session, "request", session_request)
66
+ return fake_http
@@ -0,0 +1,118 @@
1
+ from datetime import datetime, timedelta, timezone
2
+
3
+ import pytest
4
+ import requests
5
+ from python_sdk_remote.utilities import our_delete_env, our_set_env
6
+
7
+ from github_local.src.github_local import GitHubLocal, GitHubLocalException, is_branch_of_key
8
+
9
+ API = "https://api.github.com"
10
+ REPO = "jira-local-python-package"
11
+ REFS = f"{API}/repos/circles-zone/{REPO}/git/matching-refs/heads"
12
+
13
+
14
+ @pytest.fixture
15
+ def github_local() -> GitHubLocal:
16
+ github_local = GitHubLocal(token="github-token")
17
+ return github_local
18
+
19
+
20
+ def commit_time(age: timedelta) -> str:
21
+ commit_time_result = (datetime.now(timezone.utc) - age).strftime("%Y-%m-%dT%H:%M:%SZ")
22
+ return commit_time_result
23
+
24
+
25
+ def test_get_keys_merged_to_dev_searches_in_batches_of_5(fake_http, github_local):
26
+ fake_http.get(f"{API}/search/issues", json={"items": [
27
+ {"title": "feature/BU-1-a-Yuval-Rotich"}, {"title": "feature/bu-3-b (also BU-99 not asked)"}, {}]})
28
+ fake_http.get(f"{API}/search/issues", json={"items": []})
29
+
30
+ merged_keys = github_local.get_keys_merged_to_dev([f"BU-{number}" for number in range(1, 7)])
31
+
32
+ assert merged_keys == {"BU-1", "BU-3"}
33
+ assert fake_http.calls[0].params["q"] == ("org:circles-zone is:pr is:merged base:dev in:title "
34
+ "BU-1 OR BU-2 OR BU-3 OR BU-4 OR BU-5")
35
+ assert fake_http.calls[1].params["q"].endswith("in:title BU-6")
36
+ assert github_local.session.headers["Authorization"] == "Bearer github-token"
37
+
38
+
39
+ def test_get_keys_merged_to_dev_reads_all_the_pages(fake_http, github_local):
40
+ fake_http.get(f"{API}/search/issues", json={"items": [{"title": "feature/BU-9-x"}] * 99 + [{"title": "x"}]})
41
+ fake_http.get(f"{API}/search/issues", json={"items": [{"title": "feature/BU-1-x"}]})
42
+
43
+ assert github_local.get_keys_merged_to_dev(["BU-1", "BU-9"]) == {"BU-1", "BU-9"}
44
+ assert [call.params["page"] for call in fake_http.calls] == [1, 2]
45
+
46
+
47
+ def test_get_keys_merged_to_dev_stops_at_the_github_search_limit(fake_http, github_local):
48
+ fake_http.get(f"{API}/search/issues", json={"items": [{"title": "x"}] * 100})
49
+
50
+ github_local.get_keys_merged_to_dev(["BU-1"])
51
+
52
+ assert len(fake_http.calls) == 10
53
+
54
+
55
+ def test_get_keys_merged_to_dev_without_keys_calls_github_zero_times(fake_http, github_local):
56
+ assert github_local.get_keys_merged_to_dev([]) == set()
57
+ assert len(fake_http.calls) == 0
58
+
59
+
60
+ def test_search_not_found_is_an_error_and_not_an_empty_list(fake_http, github_local):
61
+ fake_http.get(f"{API}/search/issues", status=404, json={"message": "Not Found"})
62
+
63
+ with pytest.raises(GitHubLocalException, match="404"):
64
+ github_local.get_keys_merged_to_dev(["BU-1"])
65
+
66
+
67
+ def test_get_branches_of_exactly_this_key_with_their_age(fake_http, github_local):
68
+ fake_http.get(f"{REFS}/feature/BU-1", json=[
69
+ {"ref": "refs/heads/feature/BU-1-a-Yuval-Rotich", "object": {"sha": "abc"}},
70
+ {"ref": "refs/heads/feature/BU-10-other", "object": {"sha": "def"}}])
71
+ fake_http.get(f"{REFS}/BU-1", status=404)
72
+ fake_http.get(f"{API}/repos/circles-zone/{REPO}/commits/abc",
73
+ json={"commit": {"committer": {"date": commit_time(timedelta(days=3))}}})
74
+
75
+ branches = github_local.get_branches(repo_name=REPO, key="BU-1")
76
+
77
+ assert [(branch["repo_name"], branch["branch_name"]) for branch in branches] == \
78
+ [(REPO, "feature/BU-1-a-Yuval-Rotich")]
79
+ assert timedelta(days=3) - timedelta(minutes=1) < branches[0]["age"] < timedelta(days=3, minutes=1)
80
+
81
+
82
+ @pytest.mark.parametrize("branch_name, is_of_key", [
83
+ ("feature/BU-1-a", True), ("feature/BU-1", True), ("BU-1_old", True), ("bu-1-lower", True),
84
+ ("feature/BU-10-a", False), ("BU-12", False), ("feature/other-BU-1", False)])
85
+ def test_is_branch_of_key(branch_name, is_of_key):
86
+ assert is_branch_of_key(branch_name, "BU-1") == is_of_key
87
+
88
+
89
+ @pytest.mark.parametrize("status", [403, 429, 500])
90
+ def test_github_errors_raise(fake_http, github_local, status):
91
+ fake_http.get(f"{API}/search/issues", status=status, body="error")
92
+
93
+ with pytest.raises(GitHubLocalException, match=str(status)):
94
+ github_local.get_keys_merged_to_dev(["BU-1"])
95
+
96
+
97
+ def test_github_invalid_json_raises(fake_http, github_local):
98
+ fake_http.get(f"{API}/search/issues", body="<html>not json</html>")
99
+
100
+ with pytest.raises(GitHubLocalException, match="invalid response"):
101
+ github_local.get_keys_merged_to_dev(["BU-1"])
102
+
103
+
104
+ def test_github_unreachable_raises(fake_http, github_local):
105
+ fake_http.get(f"{API}/search/issues", body=requests.ConnectionError("refused"))
106
+
107
+ with pytest.raises(GitHubLocalException, match="unreachable"):
108
+ github_local.get_keys_merged_to_dev(["BU-1"])
109
+
110
+
111
+ def test_token_is_read_from_environment_variable():
112
+ our_set_env("GITHUB_TOKEN", "env-token")
113
+ try:
114
+ github_local = GitHubLocal()
115
+ finally:
116
+ our_delete_env("GITHUB_TOKEN")
117
+
118
+ assert github_local.session.headers["Authorization"] == "Bearer env-token"
@@ -0,0 +1,23 @@
1
+ Metadata-Version: 2.4
2
+ Name: github-local
3
+ Version: 0.0.1b3763
4
+ Summary: PyPI github-local Python Package owned by Circlez.ai
5
+ Home-page: https://github.com/circles-zone/github-local-python-package
6
+ Author: Circles
7
+ Author-email: info@circlez.ai
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Operating System :: OS Independent
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: python-sdk-remote
12
+ Requires-Dist: requests
13
+ Dynamic: author
14
+ Dynamic: author-email
15
+ Dynamic: classifier
16
+ Dynamic: description
17
+ Dynamic: description-content-type
18
+ Dynamic: home-page
19
+ Dynamic: requires-dist
20
+ Dynamic: summary
21
+
22
+ PyPI github-local Python Package owned by Circlez.ai
23
+ GHA: https://github.com/circles-zone/github-local-python-package/actions
@@ -0,0 +1,21 @@
1
+ .coveragerc
2
+ .flake8
3
+ README.md
4
+ pyproject.toml
5
+ pytest.ini
6
+ requirements.txt
7
+ setup.py
8
+ python_packages/conftest.py
9
+ python_packages/github_local/__init__.py
10
+ python_packages/github_local.egg-info/PKG-INFO
11
+ python_packages/github_local.egg-info/SOURCES.txt
12
+ python_packages/github_local.egg-info/dependency_links.txt
13
+ python_packages/github_local.egg-info/requires.txt
14
+ python_packages/github_local.egg-info/top_level.txt
15
+ python_packages/github_local/src/__init__.py
16
+ python_packages/github_local/src/constants_github_local.py
17
+ python_packages/github_local/src/github_local.py
18
+ python_packages/github_local/tests/__init__.py
19
+ python_packages/github_local/tests/unit/__init__.py
20
+ python_packages/github_local/tests/unit/conftest.py
21
+ python_packages/github_local/tests/unit/github_local_unit_test.py
@@ -0,0 +1,2 @@
1
+ python-sdk-remote
2
+ requests
@@ -0,0 +1,3 @@
1
+ python-sdk-remote # https://pypi.org/project/python-sdk-remote/
2
+ python-dotenv # https://pypi.org/project/python-dotenv/ conftest.py
3
+ requests # https://pypi.org/project/requests/
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,95 @@
1
+ # serverless.com repo "python -m build" works without setup.py
2
+ # Should update package_dir if not using our recommended directory structure
3
+
4
+ import setuptools
5
+
6
+ # For reading the version my_package/_version.py or my_package/__init__.py
7
+
8
+ import codecs
9
+ import os
10
+
11
+
12
+ def read(rel_path):
13
+ here = os.path.abspath(os.path.dirname(__file__))
14
+ with codecs.open(os.path.join(here, rel_path), 'r') as fp:
15
+ content = fp.read()
16
+ return content
17
+
18
+
19
+ def get_version(rel_path):
20
+ for line in read(rel_path).splitlines():
21
+ if line.startswith('__version__'):
22
+ version = line.split('"')[1] # Or "'", depending on the quotes used
23
+ return version
24
+ raise RuntimeError("Unable to find version string.")
25
+
26
+
27
+ # TODO: Change the PACKAGE_NAME to the package's name - Either xxx-local or
28
+ # xxx-remote (without the -python-package suffix). Only lowercase, no
29
+ # underlines.
30
+ # Used by pypa/gh-action-pypi-publish
31
+ # Package Name should be identical to the inner directory name
32
+ # Changing the package name here, will cause a change in the package directory
33
+ # name as well
34
+ # PACKAGE_NAME should be singular if handling only one instance
35
+ # PACKAGE_NAME should not include the word "main"
36
+
37
+ # e.g.: queue-local, without python-package suffix
38
+ PACKAGE_NAME = "github-local"
39
+ NEW_LINE = "\n"
40
+
41
+ package_dir = PACKAGE_NAME.replace("-", "_")
42
+ # If we need backward-compatible:
43
+ # old_package_dir = "old_package_name"
44
+
45
+ PACKAGE_DESCRIPTION = f"PyPI {PACKAGE_NAME} Python Package owned by Circlez.ai"
46
+
47
+ setuptools.setup(
48
+ name=PACKAGE_NAME,
49
+ # Increase this number every time you make a change
50
+ # want to publish. After 0.0.9 switch to 0.0.10 and not 0.1.0
51
+ # version can't be 0.0.
52
+ # If you find yourself increasing the version in more than one patch number (it might indicate there are multiple branches, which you should submit their PRs before your PR) # noqa: E501
53
+ # Updating the b{{JiraWorkItemId}} done automatically by makec.ps1 / make_py.ps1
54
+ # TODO add the Jira Work Item (Jira Issue) number after the version, i.e., 0.0.1b2432
55
+ # TODO: According to GitFlow, in the Feature Branch, please update after the letter 'b' the Jira Work Item ID, and in the exceptional case you can't get a Jira Work Item directly or using the Slack Channel, please use the PR number. Semantic Version simver.org
56
+ version='0.0.1b3763', # https://pypi.org/project/github-local#History
57
+ # TODO version=get_version("{{PackageDirectorySnake}}/__init__.py"),
58
+ author="Circles",
59
+ author_email="info@circlez.ai",
60
+ description=f"{PACKAGE_DESCRIPTION}",
61
+ # long_description=f"{description}",
62
+ long_description =f"{PACKAGE_DESCRIPTION}" + NEW_LINE # noqa E501
63
+ + "GHA: https://github.com/circles-zone/github-local-python-package/actions", # noqa E501
64
+
65
+ long_description_content_type='text/markdown',
66
+ url=f"https://github.com/circles-zone/{PACKAGE_NAME}-python-package",
67
+ # packages=[package_dir],
68
+ # packages=[package_dir, old_package_dir],
69
+ packages=setuptools.find_packages(where="python_packages", exclude=["*.tests", "*.tests.*"]),
70
+ package_dir={"": "python_packages"},
71
+
72
+ # I'm not sure we need package_dir
73
+ # package_dir={package_dir: f'{package_dir}/src'},
74
+ # TODO Unfortunately in event-main-local-restapi there are no
75
+ # repo-directory and no package directory (flat directory structure)
76
+ # package_dir={package_dir: f'src'},
77
+
78
+ # package_dir={package_dir: f'{package_dir}/src',
79
+ # old_package_dir: f'{package_dir}/src'},
80
+ package_data={package_dir: ['*.py']},
81
+ classifiers=[
82
+ "Programming Language :: Python :: 3",
83
+ # https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#license
84
+ # TODO Fix all repos, especially the Python templates
85
+ # "License :: MIT AND (Apache-2.0 OR BSD-2-Clause)",
86
+ "Operating System :: OS Independent",
87
+ ],
88
+ # Do not add packages needed only for tests, i.e., packages for get_test_xxx(
89
+ # TODO: Update which packages to include with this package in production
90
+ # (dependencies) - Not for development/testing
91
+ install_requires=[
92
+ 'python-sdk-remote',
93
+ 'requests',
94
+ ]
95
+ )