Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 0 additions & 31 deletions .github/actions/build-package/action.yaml

This file was deleted.

95 changes: 54 additions & 41 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -1,47 +1,60 @@
name: release

on:
on:
push:
tags:
- '*'
- "*"

jobs:
release-test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- uses: ./.github/actions/build-package

- name: Set up a fresh environment and run tests
run: |
python -m venv venv
source venv/bin/activate
pip install dist/*.tar.gz
pip install dist/*.whl
pip install -e .[test]
pytest
release:
runs-on: ubuntu-22.04
needs: release-test

steps:
- uses: actions/checkout@v4

- name: Set up Python 3.8
uses: actions/setup-python@v5
with:
python-version: 3.8

- name: Compare tags
run: |
PKG_VERSION=`grep '__version__' mapbox_tilesets/__init__.py | sed -E "s/^.*['\"](.*)['\"].*$/\1/"`
echo "Checking that package version [v$PKG_VERSION] matches release tag [${{ github.ref_name }}]"
[ "${{ github.ref_type }}" = "tag" ] && [ "${{ github.ref_name }}" = "v$PKG_VERSION" ]
- uses: ./.github/actions/build-package

- name: Run deployment
run:
twine upload dist/* -r pypi -u __token__ -p ${{ secrets.PYPI_PASSWORD }}
release-test:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4

- name: Set up uv
uses: astral-sh/setup-uv@v4
with:
python-version: "3.10"

- name: Build package
run: uv build

- name: Set up a fresh environment and run tests
run: |
uv venv
uv pip install dist/*.tar.gz
uv pip install dist/*.whl
uv pip install pytest
uv run pytest
release:
Comment on lines +10 to +30

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 5 days ago

In general, to fix this issue you must explicitly declare a permissions block either at the workflow root (applies to all jobs) or per job, and grant only the minimal privileges required. When a workflow only checks out code and runs builds/tests and external deployments, the minimal permissions for GITHUB_TOKEN are typically contents: read.

For this specific workflow in .github/workflows/release.yaml, none of the steps perform repository writes or use GitHub APIs that require more than read access. The safest and simplest fix is to add a top‑level permissions: block after the name: (or before jobs:) specifying contents: read. This will apply to both release-test and release jobs, since neither defines its own permissions. No other behavior will change: actions/checkout@v4 works with contents: read, and the PyPI upload uses a separate secret, unaffected by GITHUB_TOKEN permissions.

Concretely:

  • Edit .github/workflows/release.yaml.

  • Insert:

    permissions:
      contents: read

    between the name: release line and the on: block.
    No imports, methods, or additional definitions are needed; this is purely a YAML configuration change.

Suggested changeset 1
.github/workflows/release.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -1,5 +1,8 @@
 name: release
 
+permissions:
+  contents: read
+
 on:
   push:
     tags:
EOF
@@ -1,5 +1,8 @@
name: release

permissions:
contents: read

on:
push:
tags:
Copilot is powered by AI and may make mistakes. Always verify output.
runs-on: ubuntu-22.04
needs: release-test

steps:
- uses: actions/checkout@v4

- name: Set up uv
uses: astral-sh/setup-uv@v4
with:
python-version: "3.10"

- name: Compare tags
run: |
PKG_VERSION=`grep '__version__' mapbox_tilesets/__init__.py | sed -E "s/^.*['\"](.*)['\"].*$/\1/"`
echo "Checking that package version [v$PKG_VERSION] matches release tag [${{ github.ref_name }}]"
[ "${{ github.ref_type }}" = "tag" ] && [ "${{ github.ref_name }}" = "v$PKG_VERSION" ]
- name: Build package
run: uv build

- name: Install Twine
run: |
uv venv
uv pip install twine
- name: Validate deployment
run: uv run twine check dist/*

- name: Run deployment
run: uv run twine upload dist/* -r pypi -u __token__ -p ${{ secrets.PYPI_PASSWORD }}
Comment on lines +31 to +60

Check warning

Code scanning / CodeQL

Workflow does not contain permissions Medium

Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read}

Copilot Autofix

AI 5 days ago

In general, the fix is to explicitly declare permissions for the workflow or for individual jobs so that the GITHUB_TOKEN has only the minimal rights needed. Since this workflow does not modify repository contents, issues, or pull requests, it can safely limit contents to read and leave all other scopes at their default of none.

The best, least-intrusive fix is to add a workflow-level permissions block near the top of .github/workflows/release.yaml, so it applies to both release-test and release jobs. Specifically, after the name: release line and before the on: trigger configuration, add:

permissions:
  contents: read

No other steps, secrets, or environment variables rely on elevated GITHUB_TOKEN permissions, so this change will not break existing functionality. No imports, methods, or additional definitions are required because this is purely a YAML configuration change within the workflow file.

Suggested changeset 1
.github/workflows/release.yaml

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml
--- a/.github/workflows/release.yaml
+++ b/.github/workflows/release.yaml
@@ -1,4 +1,6 @@
 name: release
+permissions:
+  contents: read
 
 on:
   push:
EOF
@@ -1,4 +1,6 @@
name: release
permissions:
contents: read

on:
push:
Copilot is powered by AI and may make mistakes. Always verify output.
26 changes: 10 additions & 16 deletions .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,44 +9,38 @@ jobs:
test:
strategy:
matrix:
include:
- python-version: 3.8
os: ubuntu-22.04
- python-version: 3.9
os: ubuntu-22.04
os: ["ubuntu-22.04"]
python-version: ["3.10", "3.11", "3.12"]

runs-on: ${{ matrix.os }}

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
- name: Set up uv
uses: astral-sh/setup-uv@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
pip install "importlib-metadata==4.8.3"
pip install -r requirements.txt -e .[test]
run: uv sync --group dev --extra estimate-area

- name: Show Python and pytest versions
run: |
python --version
pytest --version
uv run python --version
uv run pytest --version

- name: Run pre-commit checks
run: pre-commit run --all-files
run: uv run pre-commit run --all-files

- name: Run tests with coverage
run: pytest --cov --cov-config=.coveragerc --cov-report=xml
run: uv run pytest --cov --cov-config=.coveragerc --cov-report=xml

- name: List all files in current directory
run: ls -la

- name: Upload coverage to GitHub (optional, internal)
if: matrix.python-version == '3.8'
if: matrix.python-version == '3.10'
uses: actions/upload-artifact@v4
with:
name: coverage-report
Expand Down
22 changes: 4 additions & 18 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
repos:
-
repo: 'https://github.com/ambv/black'
# 18.6b1
rev: 22.3.0
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.14.10
hooks:
- id: black
args: ['--safe']
-
repo: 'https://github.com/PyCQA/flake8'
rev: 5.0.4
hooks:
- id: flake8
args: [
# E501 let black handle all line length decisions
# W503 black conflicts with "line break before operator" rule
# E203 black conflicts with "whitespace before ':'" rule
# E231 black conflicts with "whitespace after ':'" rule
# E722 bare excepts need to be addressed
'--ignore=E501,W503,E203,E722,E231']
- id: ruff
- id: ruff-format
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@

=======

# 2.1.0 (2025-12-23)
- Replace black with ruff

# 2.0.0 (2025-12-23)
- Migrates metadata to pyproject.toml
- Drops support for Python versions < 3.10

# 1.14.0 (2025-04-23)
- Added command `tilesets upload-changeset` that uploads a changeset file.
- Added command `tilesets publish-changesets` that publishes changesets for a incrementally updatable tileset.
Expand Down
58 changes: 19 additions & 39 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,60 +3,40 @@
Hi there! Welcome to the tilesets-cli contributing document. Issues, comments, and pull requests are welcome. Please tag @mapbox/maps-api for any questions or reviews.

## Installation
First, clone the repo and `cd` into the folder:
```shell

Install uv (https://docs.astral.sh/uv/) and then clone the repo and `cd` into the folder:

```bash
# clone
git clone [email protected]:mapbox/tilesets-cli.git
cd tilesets-cli

# virtual env (optional)
mkvirtualenv tilesets-cli
# install deps (creates .venv)
uv sync --group dev

# install deps
pip install -e '.[test]'
# include optional estimate-area dependencies
uv sync --group dev --extra estimate-area

# confirm installation was successful
tilesets --help
tilesets --version
uv run tilesets --help
uv run tilesets --version
```

## Pre-commit hooks
We use [pre-commit hooks](https://pre-commit.com/) to auto-format and validate code before committing. `pre-commit` is included with the `[test]` extras, but you must run:
```
$ pre-commit install
```
within the repo to have the actions specified in `.pre-commit-config.yaml` registered.

After this, when committing, you'll see:
```
git commit -m 'update version'
black....................................................................Passed
Flake8...................................................................Passed
```
If your pre-commit hooks ran successfully. Note that `black` modifies your code, which means that if there is a syntax error you'll first see something like:
```
git commit -m '{message}'
black....................................................................Failed
hookid: black

Files were modified by this hook. Additional output:

reformatted this/file/was/reformatted.py
All done! ✨ 🍰 ✨
1 file reformatted.
We use [pre-commit hooks](https://pre-commit.com/) to auto-format and validate code before committing. `pre-commit` is included with the `dev` dependency group, but you must run:

Flake8...................................................................Failed
hookid: flake8

this/file/was/reformatted.py:{line}:{character}: {what was incorrect}
```bash
$ uv run pre-commit install
```
After which you can add these changes and commit again. Note that failing pre-commit commands mean that the commit has not taken place: you must commit again!
within the repo to have the actions specified in `.pre-commit-config.yaml` registered.


## Release process

Releases to PyPi are handled via Github Actions and GitHub tags. Once changes have been merged to master:

1. Update the version in mapbox_tilesets/__init__.py
1. Update the version in `pyproject.toml`
2. Update the changelog
3. Commit changes to **your branch**. For example `git commit -am '0.2.0' && git push origin HEAD`
4. Get a review and merge your changes to master.
Expand All @@ -67,14 +47,14 @@ Releases to PyPi are handled via Github Actions and GitHub tags. Once changes ha

## Tests

All tests are runnable with pytest. pytest is not installed by default and can be installed with the pip test extras
All tests are runnable with pytest. pytest is installed via the `dev` dependency group:

```shell
pip install -e '.[test]'
uv sync --group dev
```

Running tests

```
pytest
uv run pytest
```
15 changes: 5 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,18 @@ CLI for interacting with and preparing data for the [Mapbox Tiling Service](http

## Requirements

- Python >= 3.6 (can be installed via virtualenv)
- Recommended: [virtualenv](https://virtualenv.pypa.io/) / [virtualenvwrapper](https://virtualenvwrapper.readthedocs.io/en/latest/)
- Python >= 3.10

## Basic installation

`pip install mapbox-tilesets` will install everything but [`estimate-area`](#estimate-area).
`pip install mapbox-tilesets` will install everything but the [`estimate-area`](#estimate-area) command.

## Installing optional `estimate-area` command

If you are using an x86 Mac or Linux machine, run:
`pip install 'mapbox-tilesets[estimate-area]'`

Otherwise, you will need to install some dependencies.
`pip install 'mapbox-tilesets[estimate-area]'`. Otherwise, you will need to install some dependencies.

### arm64 MacOS

If you're on an arm64 Mac (e.g., with an M1 chip), you'll need to install [GDAL](https://gdal.org/) first. On Mac, a simple way is to use [Homebrew](https://brew.sh/):
If you're on an Arm64 Mac, you'll need to install [GDAL](https://gdal.org/) first. On Mac, a simple way is to use [Homebrew](https://brew.sh/):

```sh
$ brew install gdal
Expand Down Expand Up @@ -507,4 +502,4 @@ Publishes changesets for a tileset that supports incremental updates. This comma

```shell
tilesets publish-changesets <tileset_id> --changeset /path/to/changeset.json
```
```
8 changes: 7 additions & 1 deletion mapbox_tilesets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
"""mapbox_tilesets package"""

__version__ = "1.14.0"
from importlib.metadata import PackageNotFoundError, version as _pkg_version

try:
__version__ = _pkg_version("mapbox-tilesets")
except PackageNotFoundError:
# Fallback for development mode
__version__ = "0.0.0.dev"
4 changes: 3 additions & 1 deletion mapbox_tilesets/errors.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Error handling for the tilesets CLI"""

from click import ClickException


Expand All @@ -17,6 +18,7 @@ def __init__(self, message):
message: str
Error description
"""
super().__init__(message)
self.message = message


Expand All @@ -25,7 +27,7 @@ class TilesetNameError(TilesetsError):

def __init__(self, tileset_id):
self.tileset_id = tileset_id
self.message = "Invalid Tileset ID"
super().__init__("Invalid Tileset ID")

def __str__(self):
return "{tileset_id} -> {message}".format(
Expand Down
Loading
Loading