Skip to content

Commit b17e947

Browse files
authored
Fixed the ability to override the API URL for Socket Requests (#64)
* Fixed the ability to override the API URL for Socket Requests * Changed over to hatchling for releases * Updated release workflows for hatchling build * Adding needed modules for build * Added pre-commit hook to sync tag to version in file * Fixing pr-release for hatch logic * Bumping version for deploy * Fixing build process * Change build process for PR build * Added permissions for Trusted Publishing * Fixed typo in preview logic * Removing unneeded command breaking build * Add debug for build process * Bump version * Added workaround for naming bug when pushing via OIDC * Moving to static version and pre commit hook to fix version publishing issue * Adding back in auto increment of version * testing version bump * Updating version logic * Updated pre-commit hook * version bumped
1 parent ec4e7f7 commit b17e947

11 files changed

+171
-71
lines changed

.github/workflows/pr-preview.yml

+17-37
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ on:
66
jobs:
77
preview:
88
runs-on: ubuntu-latest
9+
permissions:
10+
id-token: write
11+
contents: read
12+
pull-requests: write
913
steps:
1014
- uses: actions/checkout@v4
15+
with:
16+
fetch-depth: 0
1117
- uses: actions/setup-python@v5
1218
with:
1319
python-version: '3.x'
@@ -16,56 +22,30 @@ jobs:
1622
- name: Install dependencies
1723
run: |
1824
python -m pip install --upgrade pip
19-
pip install -e .
20-
21-
- name: Set preview version
22-
run: |
23-
BASE_VERSION=$(python -c "from socketsecurity import __version__; print(__version__)")
24-
PREVIEW_VERSION="${BASE_VERSION}.dev${{ github.event.pull_request.number }}${{ github.event.pull_request.commits }}"
25-
echo "VERSION=${PREVIEW_VERSION}" >> $GITHUB_ENV
25+
pip install hatchling==1.27.0 hatch==1.14.0
2626
27-
# Update version in __init__.py
28-
echo "__version__ = \"${PREVIEW_VERSION}\"" > socketsecurity/__init__.py.tmp
29-
cat socketsecurity/__init__.py | grep -v "__version__" >> socketsecurity/__init__.py.tmp
30-
mv socketsecurity/__init__.py.tmp socketsecurity/__init__.py
27+
- name: Inject full dynamic version
28+
run: python .hooks/sync_version.py --dev
3129

32-
# Verify the change
33-
echo "Updated version in __init__.py:"
34-
python -c "from socketsecurity import __version__; print(__version__)"
30+
- name: Clean previous builds
31+
run: rm -rf dist/ build/ *.egg-info
3532

36-
- name: Check if version exists on Test PyPI
37-
id: version_check
38-
env:
39-
VERSION: ${{ env.VERSION }}
33+
- name: Get Hatch version
34+
id: version
4035
run: |
41-
if curl -s -f https://test.pypi.org/pypi/socketsecurity/$VERSION/json > /dev/null; then
42-
echo "Version ${VERSION} already exists on Test PyPI"
43-
echo "exists=true" >> $GITHUB_OUTPUT
44-
else
45-
echo "Version ${VERSION} not found on Test PyPI"
46-
echo "exists=false" >> $GITHUB_OUTPUT
47-
fi
36+
VERSION=$(hatch version | cut -d+ -f1)
37+
echo "VERSION=$VERSION" >> $GITHUB_ENV
4838
4939
- name: Build package
5040
if: steps.version_check.outputs.exists != 'true'
5141
run: |
52-
pip install build
53-
python -m build
54-
55-
- name: Restore original version
56-
if: always()
57-
run: |
58-
BASE_VERSION=$(echo $VERSION | cut -d'.' -f1-3)
59-
echo "__version__ = \"${BASE_VERSION}\"" > socketsecurity/__init__.py.tmp
60-
cat socketsecurity/__init__.py | grep -v "__version__" >> socketsecurity/__init__.py.tmp
61-
mv socketsecurity/__init__.py.tmp socketsecurity/__init__.py
42+
hatch build
6243
6344
- name: Publish to Test PyPI
6445
if: steps.version_check.outputs.exists != 'true'
65-
uses: pypa/gh-action-pypi-publish@v1.8.11
46+
uses: pypa/gh-action-pypi-publish@v1.12.4
6647
with:
6748
repository-url: https://test.pypi.org/legacy/
68-
password: ${{ secrets.TEST_PYPI_TOKEN }}
6949
verbose: true
7050

7151
- name: Comment on PR

.github/workflows/release.yml

+13-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
name: Release
22
on:
3-
push:
4-
tags:
5-
- 'v*'
3+
release:
4+
types: [published]
65

76
jobs:
87
release:
98
runs-on: ubuntu-latest
9+
permissions:
10+
id-token: write
11+
contents: read
1012
steps:
1113
- uses: actions/checkout@v4
14+
with:
15+
fetch-depth: 0
1216
- uses: actions/setup-python@v5
1317
with:
1418
python-version: '3.x'
@@ -17,15 +21,15 @@ jobs:
1721
- name: Install dependencies
1822
run: |
1923
python -m pip install --upgrade pip
20-
pip install -e .
24+
pip install hatchling==1.27.0 hatch==1.14.0
2125
2226
- name: Get Version
2327
id: version
2428
run: |
25-
RAW_VERSION=$(python -c "from socketsecurity import __version__; print(__version__)")
29+
RAW_VERSION=$(hatch version)
2630
echo "VERSION=$RAW_VERSION" >> $GITHUB_ENV
2731
if [ "v$RAW_VERSION" != "${{ github.ref_name }}" ]; then
28-
echo "Error: Git tag (${{ github.ref_name }}) does not match package version (v$RAW_VERSION)"
32+
echo "Error: Git tag (${{ github.ref_name }}) does not match hatch version (v$RAW_VERSION)"
2933
exit 1
3034
fi
3135
@@ -57,14 +61,12 @@ jobs:
5761
- name: Build package
5862
if: steps.version_check.outputs.pypi_exists != 'true'
5963
run: |
60-
pip install build
61-
python -m build
64+
pip install hatchling
65+
hatch build
6266
6367
- name: Publish to PyPI
6468
if: steps.version_check.outputs.pypi_exists != 'true'
65-
uses: pypa/[email protected]
66-
with:
67-
password: ${{ secrets.PYPI_TOKEN }}
69+
uses: pypa/[email protected]
6870

6971
- name: Login to Docker Hub
7072
uses: docker/login-action@v3

.hooks/sync_version.py

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
import subprocess
3+
import pathlib
4+
import re
5+
import sys
6+
import urllib.request
7+
import json
8+
9+
INIT_FILE = pathlib.Path("socketsecurity/__init__.py")
10+
PYPROJECT_FILE = pathlib.Path("pyproject.toml")
11+
12+
VERSION_PATTERN = re.compile(r"__version__\s*=\s*['\"]([^'\"]+)['\"]")
13+
PYPROJECT_PATTERN = re.compile(r'^version\s*=\s*".*"$', re.MULTILINE)
14+
PYPI_API = "https://test.pypi.org/pypi/socketsecurity/json"
15+
16+
def read_version_from_init(path: pathlib.Path) -> str:
17+
content = path.read_text()
18+
match = VERSION_PATTERN.search(content)
19+
if not match:
20+
print(f"❌ Could not find __version__ in {path}")
21+
sys.exit(1)
22+
return match.group(1)
23+
24+
def read_version_from_git(path: str) -> str:
25+
try:
26+
output = subprocess.check_output(["git", "show", f"HEAD:{path}"], text=True)
27+
match = VERSION_PATTERN.search(output)
28+
if not match:
29+
return None
30+
return match.group(1)
31+
except subprocess.CalledProcessError:
32+
return None
33+
34+
def bump_patch_version(version: str) -> str:
35+
if ".dev" in version:
36+
version = version.split(".dev")[0]
37+
parts = version.split(".")
38+
parts[-1] = str(int(parts[-1]) + 1)
39+
return ".".join(parts)
40+
41+
def fetch_existing_versions() -> set:
42+
try:
43+
with urllib.request.urlopen(PYPI_API) as response:
44+
data = json.load(response)
45+
return set(data.get("releases", {}).keys())
46+
except Exception as e:
47+
print(f"⚠️ Warning: Failed to fetch existing versions from Test PyPI: {e}")
48+
return set()
49+
50+
def find_next_available_dev_version(base_version: str) -> str:
51+
existing_versions = fetch_existing_versions()
52+
for i in range(1, 100):
53+
candidate = f"{base_version}.dev{i}"
54+
if candidate not in existing_versions:
55+
return candidate
56+
print("❌ Could not find available .devN slot after 100 attempts.")
57+
sys.exit(1)
58+
59+
def inject_version(version: str):
60+
print(f"🔁 Updating version to: {version}")
61+
62+
# Update __init__.py
63+
init_content = INIT_FILE.read_text()
64+
new_init_content = VERSION_PATTERN.sub(f"__version__ = '{version}'", init_content)
65+
INIT_FILE.write_text(new_init_content)
66+
67+
# Update pyproject.toml
68+
pyproject = PYPROJECT_FILE.read_text()
69+
if PYPROJECT_PATTERN.search(pyproject):
70+
new_pyproject = PYPROJECT_PATTERN.sub(f'version = "{version}"', pyproject)
71+
else:
72+
new_pyproject = re.sub(r"(\[project\])", rf"\1\nversion = \"{version}\"", pyproject)
73+
PYPROJECT_FILE.write_text(new_pyproject)
74+
75+
def main():
76+
dev_mode = "--dev" in sys.argv
77+
current_version = read_version_from_init(INIT_FILE)
78+
previous_version = read_version_from_git("socketsecurity/__init__.py")
79+
80+
print(f"Current: {current_version}, Previous: {previous_version}")
81+
82+
if current_version == previous_version:
83+
if dev_mode:
84+
base_version = current_version.split(".dev")[0] if ".dev" in current_version else current_version
85+
new_version = find_next_available_dev_version(base_version)
86+
inject_version(new_version)
87+
print("⚠️ Version was unchanged — auto-bumped. Please git add + commit again.")
88+
sys.exit(0)
89+
else:
90+
new_version = bump_patch_version(current_version)
91+
inject_version(new_version)
92+
print("⚠️ Version was unchanged — auto-bumped. Please git add + commit again.")
93+
sys.exit(1)
94+
else:
95+
print("✅ Version already bumped — proceeding.")
96+
sys.exit(0)
97+
98+
if __name__ == "__main__":
99+
main()

.pre-commit-config.yaml

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
repos:
2+
- repo: local
3+
hooks:
4+
- id: sync-version
5+
name: Sync __version__ with hatch version
6+
entry: python .hooks/sync_version.py
7+
language: python
8+
always_run: true
9+
pass_filenames: false

Pipfile.lock

+2-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# 1. Clone the repo and create a virtualenv (Python 3.12+)
2+
python3.12 -m venv .venv
3+
source .venv/bin/activate
4+
5+
# 2. Install dependencies
6+
pip install --upgrade pip
7+
pip install .[dev]
8+
9+
# 3. Set up pre-commit hooks
10+
pre-commit install

pyproject.toml

+14-16
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,22 @@
11
[build-system]
2-
requires = ["setuptools >= 61.0"]
3-
build-backend = "setuptools.build_meta"
2+
requires = [
3+
"hatchling"
4+
]
5+
build-backend = "hatchling.build"
46

57
[project]
68
name = "socketsecurity"
7-
dynamic = ["version"]
8-
requires-python = ">= 3.9"
9+
version = "2.0.32"
10+
requires-python = ">= 3.10"
11+
license = {"file" = "LICENSE"}
912
dependencies = [
1013
'requests',
1114
'mdutils',
1215
'prettytable',
1316
'GitPython',
1417
'packaging',
1518
'python-dotenv',
16-
'socket-sdk-python>=2.0.9'
19+
'socket-sdk-python>=2.0.15'
1720
]
1821
readme = "README.md"
1922
description = "Socket Security CLI for CI/CD"
@@ -43,6 +46,8 @@ dev = [
4346
"ruff>=0.3.0",
4447
"twine", # for building
4548
"pip-tools>=7.4.0", # for pip-compile
49+
"pre-commit",
50+
"hatch"
4651
]
4752

4853
[project.scripts]
@@ -51,16 +56,6 @@ socketcli = "socketsecurity.socketcli:cli"
5156
[project.urls]
5257
Homepage = "https://socket.dev"
5358

54-
[tool.setuptools.packages.find]
55-
include = [
56-
"socketsecurity*"
57-
]
58-
59-
[tool.setuptools.dynamic]
60-
version = {attr = "socketsecurity.__version__"}
61-
62-
63-
6459
[tool.coverage.run]
6560
source = ["socketsecurity"]
6661
branch = true
@@ -163,4 +158,7 @@ docstring-code-format = false
163158
#
164159
# This only has an effect when the `docstring-code-format` setting is
165160
# enabled.
166-
docstring-code-line-length = "dynamic"
161+
docstring-code-line-length = "dynamic"
162+
163+
[tool.hatch.build.targets.wheel]
164+
include = ["socketsecurity", "LICENSE"]

requirements-dev.lock

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
# generate-hashes: false
1010
# universal: false
1111

12-
-e file:.
12+
hatchling==1.27.0
13+
hatch==1.14.0
1314
argparse==1.4.0
1415
# via socketsecurity
1516
certifi==2024.12.14
@@ -60,7 +61,7 @@ requests==2.32.3
6061
# via socketsecurity
6162
smmap==5.0.2
6263
# via gitdb
63-
socket-sdk-python @ file:///Users/erichibbs/code/socket/socket-sdk-python
64+
socket-sdk-python==2.0.15
6465
# via socketsecurity
6566
typing-extensions==4.12.2
6667
# via socket-sdk-python

requirements.lock

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# generate-hashes: false
1010
# universal: false
1111

12-
-e file:.
1312
argparse==1.4.0
1413
# via socketsecurity
1514
certifi==2024.12.14
@@ -60,7 +59,7 @@ requests==2.32.3
6059
# via socketsecurity
6160
smmap==5.0.2
6261
# via gitdb
63-
socket-sdk-python @ file:///Users/erichibbs/code/socket/socket-sdk-python
62+
socket-sdk-python==2.0.15
6463
# via socketsecurity
6564
typing-extensions==4.12.2
6665
# via socket-sdk-python

socketsecurity/__init__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
__author__ = 'socket.dev'
2-
__version__ = '2.0.14'
2+
__version__ = '2.0.32'
3+

socketsecurity/socketcli.py

+1
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ def main_code():
7171
)
7272
log.debug("loaded socket_config")
7373
client = CliClient(socket_config)
74+
sdk.api.api_url = socket_config.api_url
7475
log.debug("loaded client")
7576
core = Core(socket_config, sdk)
7677
log.debug("loaded core")

0 commit comments

Comments
 (0)