Skip to content

Commit eaaf8bb

Browse files
authored
Merge pull request #5 from maxmind/greg/eng-4103
Prepare repo for initial release
2 parents 06c1a05 + d495e8a commit eaaf8bb

19 files changed

Lines changed: 387 additions & 39 deletions

.github/dependabot.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: uv
4+
directory: /
5+
schedule:
6+
interval: daily
7+
time: '14:00'
8+
open-pull-requests-limit: 10
9+
cooldown:
10+
default-days: 7
11+
- package-ecosystem: github-actions
12+
directory: /
13+
schedule:
14+
interval: daily
15+
time: '14:00'
16+
cooldown:
17+
default-days: 7
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: "Code scanning - action"
2+
3+
on:
4+
push:
5+
branches-ignore:
6+
- 'dependabot/**'
7+
pull_request:
8+
schedule:
9+
- cron: '0 11 * * 2'
10+
11+
permissions: {}
12+
13+
jobs:
14+
CodeQL-Build:
15+
16+
runs-on: ubuntu-latest
17+
18+
permissions:
19+
security-events: write
20+
21+
steps:
22+
- name: Checkout repository
23+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
24+
with:
25+
fetch-depth: 2
26+
persist-credentials: false
27+
28+
- run: git checkout HEAD^2
29+
if: ${{ github.event_name == 'pull_request' }}
30+
31+
- name: Initialize CodeQL
32+
uses: github/codeql-action/init@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
33+
34+
- name: Autobuild
35+
uses: github/codeql-action/autobuild@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10
36+
37+
- name: Perform CodeQL Analysis
38+
uses: github/codeql-action/analyze@cdefb33c0f6224e58673d9004f47f7cb3e328b89 # v4.31.10

.github/workflows/release.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build and upload to PyPI
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
push:
7+
branches:
8+
- main
9+
release:
10+
types:
11+
- published
12+
13+
permissions: {}
14+
15+
jobs:
16+
build:
17+
name: Build source distribution
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
21+
with:
22+
persist-credentials: false
23+
24+
- name: Install the latest version of uv
25+
uses: astral-sh/setup-uv@803947b9bd8e9f986429fa0c5a41c367cd732b41 # 7.2.1
26+
27+
- name: Build
28+
run: uv build
29+
30+
- uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
31+
with:
32+
path: |
33+
dist/*.tar.gz
34+
dist/*.whl
35+
36+
upload_pypi:
37+
needs: build
38+
runs-on: ubuntu-latest
39+
environment: release
40+
permissions:
41+
id-token: write
42+
if: github.event_name == 'release' && github.event.action == 'published'
43+
steps:
44+
- uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
45+
with:
46+
name: artifact
47+
path: dist
48+
49+
- uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # 1.13.0

.github/workflows/test.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Python tests
2+
3+
on:
4+
push:
5+
pull_request:
6+
schedule:
7+
- cron: '3 15 * * SUN'
8+
9+
permissions: {}
10+
11+
jobs:
12+
test:
13+
name: test with ${{ matrix.env }} on ${{ matrix.os }}
14+
runs-on: ${{ matrix.os }}
15+
strategy:
16+
fail-fast: false
17+
matrix:
18+
env: [3.11, 3.12, 3.13, 3.14]
19+
os: [ubuntu-latest, ubuntu-24.04-arm, macos-latest, windows-latest]
20+
steps:
21+
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
22+
with:
23+
persist-credentials: false
24+
- name: Install the latest version of uv
25+
uses: astral-sh/setup-uv@803947b9bd8e9f986429fa0c5a41c367cd732b41 # 7.2.1
26+
- name: Install tox
27+
run: uv tool install --python-preference only-managed --python 3.13 tox --with tox-uv --with tox-gh
28+
- name: Install Python
29+
if: matrix.env != '3.13'
30+
run: uv python install --python-preference only-managed ${{ matrix.env }}
31+
- name: Setup test suite
32+
run: tox run -vv --notest --skip-missing-interpreters false
33+
env:
34+
TOX_GH_MAJOR_MINOR: ${{ matrix.env }}
35+
- name: Run test suite
36+
run: tox run --skip-pkg-install
37+
env:
38+
TOX_GH_MAJOR_MINOR: ${{ matrix.env }}

.github/workflows/zizmor.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: GitHub Actions Security Analysis with zizmor
2+
3+
on:
4+
push:
5+
branches: ["main"]
6+
pull_request:
7+
branches: ["**"]
8+
9+
permissions: {}
10+
11+
jobs:
12+
zizmor:
13+
runs-on: ubuntu-latest
14+
permissions:
15+
security-events: write
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
19+
with:
20+
persist-credentials: false
21+
22+
- name: Run zizmor
23+
uses: zizmorcore/zizmor-action@0dce2577a4760a2749d8cfb7a84b7d5585ebcb7d # v0.5.0

HISTORY.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
History
44
-------
55

6-
1.0.0 (2024-12-05)
6+
0.1.0 (2026-02-10)
77
++++++++++++++++++
88

99
* Initial release
File renamed without changes.

LICENSE-MIT

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Permission is hereby granted, free of charge, to any person obtaining a copy of
2+
this software and associated documentation files (the "Software"), to deal in
3+
the Software without restriction, including without limitation the rights to
4+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
5+
of the Software, and to permit persons to whom the Software is furnished to do
6+
so, subject to the following conditions:
7+
8+
The above copyright notice and this permission notice shall be included in all
9+
copies or substantial portions of the Software.
10+
11+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17+
SOFTWARE.

README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ asyncio.run(main())
9090
### Loading Configuration from File
9191

9292
```python
93+
from pathlib import Path
94+
9395
from pygeoipupdate import Config, Updater
9496

9597
config = Config.from_file(config_file=Path("/etc/GeoIP.conf"))
@@ -178,6 +180,18 @@ Options:
178180
- Configuration file: `%SYSTEMDRIVE%\ProgramData\MaxMind\GeoIPUpdate\GeoIP.conf`
179181
- Database directory: `%SYSTEMDRIVE%\ProgramData\MaxMind\GeoIPUpdate\GeoIP`
180182

183+
## Error Handling
184+
185+
When using the Python API, pygeoipupdate raises specific exceptions:
186+
187+
- `GeoIPUpdateError` — Base exception for all errors.
188+
- `ConfigError` — Invalid configuration.
189+
- `DownloadError` — Download failure.
190+
- `AuthenticationError` — Invalid account ID or license key.
191+
- `HTTPError` — HTTP error with `.status_code` and `.body` attributes.
192+
- `LockError` — Could not acquire the lock file.
193+
- `HashMismatchError` — Downloaded file hash mismatch (`.expected`, `.actual`).
194+
181195
## Running as a Cron Job
182196

183197
To keep your databases up to date, we recommend running pygeoipupdate at least
@@ -193,9 +207,21 @@ twice per week. Here's an example cron entry:
193207
- Python 3.11+
194208
- A MaxMind account with a license key
195209

196-
## License
210+
## Bug Reports
211+
212+
Please report bugs by filing an issue with [our GitHub issue
213+
tracker](https://github.com/maxmind/pygeoipupdate/issues).
214+
215+
## Versioning
216+
217+
This library uses [Semantic Versioning](https://semver.org/).
218+
219+
## Copyright and License
220+
221+
This software is Copyright (c) 2025 - 2026 by MaxMind, Inc.
197222

198-
Apache-2.0
223+
This is free software, licensed under the [Apache License, Version
224+
2.0](LICENSE-APACHE) or the [MIT License](LICENSE-MIT), at your option.
199225

200226
## Links
201227

dev-bin/release.sh

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/bin/bash
2+
3+
set -eu -o pipefail
4+
5+
# Pre-flight checks - verify all required tools are available and configured
6+
# before making any changes to the repository
7+
8+
check_command() {
9+
if ! command -v "$1" &>/dev/null; then
10+
echo "Error: $1 is not installed or not in PATH"
11+
exit 1
12+
fi
13+
}
14+
15+
# Verify gh CLI is authenticated
16+
if ! gh auth status &>/dev/null; then
17+
echo "Error: gh CLI is not authenticated. Run 'gh auth login' first."
18+
exit 1
19+
fi
20+
21+
# Verify we can access this repository via gh
22+
if ! gh repo view --json name &>/dev/null; then
23+
echo "Error: Cannot access repository via gh. Check your authentication and repository access."
24+
exit 1
25+
fi
26+
27+
# Verify git can connect to the remote (catches SSH key issues, etc.)
28+
if ! git ls-remote origin &>/dev/null; then
29+
echo "Error: Cannot connect to git remote. Check your git credentials/SSH keys."
30+
exit 1
31+
fi
32+
33+
check_command perl
34+
check_command uv
35+
36+
# Check that we're not on the main branch
37+
current_branch=$(git branch --show-current)
38+
if [ "$current_branch" = "main" ]; then
39+
echo "Error: Releases should not be done directly on the main branch."
40+
echo "Please create a release branch and run this script from there."
41+
exit 1
42+
fi
43+
44+
# Fetch latest changes and check that we're not behind origin/main
45+
echo "Fetching from origin..."
46+
git fetch origin
47+
48+
if ! git merge-base --is-ancestor origin/main HEAD; then
49+
echo "Error: Current branch is behind origin/main."
50+
echo "Please merge or rebase with origin/main before releasing."
51+
exit 1
52+
fi
53+
54+
changelog=$(cat HISTORY.rst)
55+
56+
regex='
57+
([0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?) \(([0-9]{4}-[0-9]{2}-[0-9]{2})\)
58+
\+*
59+
60+
((.|
61+
)*)
62+
'
63+
64+
if [[ ! $changelog =~ $regex ]]; then
65+
echo "Could not find date line in change log!"
66+
exit 1
67+
fi
68+
69+
version="${BASH_REMATCH[1]}"
70+
date="${BASH_REMATCH[3]}"
71+
notes="$(echo "${BASH_REMATCH[4]}" | sed -n -E '/^[0-9]+\.[0-9]+\.[0-9]+(-[a-zA-Z0-9.]+)?/,$!p')"
72+
73+
if [[ "$date" != "$(date +"%Y-%m-%d")" ]]; then
74+
echo "$date is not today!"
75+
exit 1
76+
fi
77+
78+
tag="v$version"
79+
80+
if [ -n "$(git status --porcelain)" ]; then
81+
echo ". is not clean." >&2
82+
exit 1
83+
fi
84+
85+
perl -pi -e "s/(?<=^version = \").+?(?=\")/$version/gsm" pyproject.toml
86+
87+
echo $"Test results:"
88+
uv run tox
89+
90+
echo $'\nDiff:'
91+
git diff
92+
93+
echo $'\nRelease notes:'
94+
echo "$notes"
95+
96+
read -r -e -p "Commit changes and push to origin? " should_push
97+
98+
if [ "$should_push" != "y" ]; then
99+
echo "Aborting"
100+
exit 1
101+
fi
102+
103+
git commit -m "Update for $tag" -a
104+
105+
git push
106+
107+
gh release create --target "$(git branch --show-current)" -t "$version" -n "$notes" "$tag"

0 commit comments

Comments
 (0)