Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce py3.13, ruff, leverage hatch #359

Merged
merged 4 commits into from
Feb 26, 2025
Merged
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
1 change: 1 addition & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ba1c3bb3f0a1c9e85a8bb23012754ddc210e6567 # style: ruff linter/formatter migration
70 changes: 70 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
name: Build

on:
workflow_call:
workflow_dispatch:

env:
PYTHONUNBUFFERED: "1"
FORCE_COLOR: "1"

jobs:
test:
uses: ./.github/workflows/test.yml
permissions:
contents: read
build:
name: Build distribution 📦
runs-on: ubuntu-latest
needs:
- test
steps:
- name: Checkout source code
uses: actions/checkout@v4

- name: Set up Python 3.12
uses: actions/setup-python@v5
with:
python-version-file: pyproject.toml

- name: Install Hatch
uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc

- name: Set package version from tag
run: hatch version $(git describe --tags --always)

- name: Build package
run: hatch build

- name: Store the distribution packages
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/

sign-release:
name: >-
Sign the Python 🐍 distribution 📦 with Sigstore
needs:
- build
runs-on: ubuntu-latest
permissions:
id-token: write # IMPORTANT: mandatory for sigstore
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Sign the dists with Sigstore
uses: sigstore/[email protected]
with:
inputs: >-
./dist/*.tar.gz
./dist/*.whl
- name: Store the signature files
uses: actions/upload-artifact@v4
with:
name: python-package-distributions
path: dist/
overwrite: true
42 changes: 42 additions & 0 deletions .github/workflows/prepare_release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Prepare release

on:
push:
tags:
- '*'
workflow_call:
workflow_dispatch:

env:
PYTHONUNBUFFERED: "1"
FORCE_COLOR: "1"

jobs:
build:
uses: ./.github/workflows/build.yml
permissions:
contents: read
id-token: write # IMPORTANT: mandatory for sigstore in build.yml

create-release:
needs:
- build
runs-on: ubuntu-latest
steps:
- name: Download all the dists
uses: actions/download-artifact@v4
with:
name: python-package-distributions
path: dist/
- name: Release
id: create-draft-release
uses: softprops/action-gh-release@v2
with:
files: |
./dist/*
draft: true
- name: Summary
run: |
echo "# Release summary" >> $GITHUB_STEP_SUMMARY
echo "Url: ${{ steps.create-draft-release.outputs.url }}" >> $GITHUB_STEP_SUMMARY
echo "You can now publish the release on GitHub" >> $GITHUB_STEP_SUMMARY
59 changes: 33 additions & 26 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -1,35 +1,42 @@
name: Publish on PyPI
name: Publish

on:
release:
types:
- published
workflow_call:
workflow_dispatch:

env:
PYTHONUNBUFFERED: "1"
FORCE_COLOR: "1"

jobs:
build-n-publish:
name: Build and publish to PyPI
publish-to-pypi:
name: >-
Publish Python 🐍 distribution 📦 to PyPI
if: startsWith(github.ref, 'refs/tags/') # only publish to PyPI on tag pushes
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/ariadne-codegen
permissions:
# IMPORTANT: this permission is mandatory for trusted publishing
id-token: write
contents: read

steps:
- uses: actions/checkout@master
- name: Set up Python 3.10
uses: actions/setup-python@v4
with:
python-version: "3.10"
- name: Install pypa/build
run: >-
python -m
pip install
build
--user
- name: Build a binary wheel and a source tarball
run: >-
python -m build
--sdist
--wheel
--outdir dist/
.
- name: Publish distribution to PyPI
if: startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
password: ${{ secrets.PYPI_API_TOKEN }}
- name: Download all the dists from the release
env:
GITHUB_TOKEN: ${{ github.token }}
run: >-
gh release download
'${{ github.ref_name }}'
-p '*.whl'
-p '*.tar.gz'
--dir dist/
--repo '${{ github.repository }}'
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
skip-existing: true
47 changes: 47 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
name: Tests

on:
push:
branches:
- main
pull_request:
schedule:
- cron: "0 7 * * 1,3"
workflow_call:
workflow_dispatch:

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

env:
PYTHONUNBUFFERED: "1"
FORCE_COLOR: "1"

jobs:
build:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
steps:
- name: Checkout source code
uses: actions/checkout@v4

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

- name: Install Hatch
uses: pypa/hatch@257e27e51a6a5616ed08a39a408a21c35c9931bc

- name: Run static analysis
run: hatch fmt --check

- name: Run type checking
run: hatch run types:check

- name: Run tests
run: hatch test -c -py ${{ matrix.python-version }}
50 changes: 0 additions & 50 deletions .github/workflows/tests.yml

This file was deleted.

37 changes: 25 additions & 12 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,28 +14,41 @@ You can use [GitHub issues](https://github.com/mirumee/ariadne-codegen/issues) t

## Development setup

Ariadne Code Generator is written to support Python 3.9, 3.10 and 3.11.
Ariadne Code Generator is written to support Python 3.9, 3.10, 3.11, 3.12 and 3.13.

Codebase is formatted using [black](https://github.com/ambv/black) and [isort](https://github.com/PyCQA/isort), the contents of the `ariadne-codegen` package are annotated with types and validated using [mypy](http://mypy-lang.org/index.html). [Pylint](https://github.com/pylint-dev/pylint) is used to catch errors in code.
We use [Hatch](https://github.com/pypa/hatch) for project management.

Tests are developed using [pytest](https://pytest.org/).
The codebase is formatted using [ruff](https://github.com/astral-sh/ruff).
To format the code, use the following command:
```bash
hatch fmt
```

Dev requirements can be installed using Pip extras. For example, to install all dependencies for doing local development and running the tests, run `pip install -e .[subscriptions,dev]`.
The contents of the `ariadne-codegen` package are annotated with types and validated using [mypy](http://mypy-lang.org/index.html). To run type checking with mypy, use:
```bash
hatch run types:check
```

We require all changes to be done via pull requests, and to be approved by member-ranked users before merging.

All changes should pass these linter checks:
Tests are developed using [pytest](https://pytest.org/) and are managed with Hatch.


To run the tests, use:
```bash
pylint ariadne_codegen tests
mypy ariadne_codegen --ignore-missing-imports
mypy --strict tests/main/clients/*/expected_client
mypy --strict tests/main/graphql_schemas/*/expected_schema.py
black --check .
isort . --check-only
hatch test
```


To run all checks (formatting, type checking, and tests), you can use:
```bash
hatch run check
```

We require all changes to be done via pull requests, and to be approved by member-ranked users before merging.

All changes should pass these linter checks.


## Working on issues

We consider all issues which are not assigned to anybody as being available for contributors. The **[help wanted](https://github.com/mirumee/ariadne-codegen/labels/help%20wanted)** label is used to single out issues that we consider easier or higher priority on the list of things that we would like to see.
Expand Down
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
BSD 3-Clause License

Copyright (c) 2023, Mirumee Labs
Copyright (c) 2025, Mirumee Labs
All rights reserved.

Redistribution and use in source and binary forms, with or without
Expand Down
1 change: 1 addition & 0 deletions ariadne_codegen/__about__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
__version__ = "0.0.1.dev0" # This is overwritten by Hatch in CI/CD, don't change it.
2 changes: 1 addition & 1 deletion ariadne_codegen/client_generators/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -894,7 +894,7 @@ def _generate_operation_str_assign(
value=generate_call(
func=generate_name(self._gql_func_name),
args=[
[generate_constant(l + "\n") for l in operation_str.splitlines()]
[generate_constant(l + "\n") for l in operation_str.splitlines()] # noqa: E741
],
),
lineno=lineno,
Expand Down
1 change: 0 additions & 1 deletion ariadne_codegen/client_generators/comments.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@


def get_comment(strategy: CommentsStrategy, source: Optional[str] = None) -> str:
# pylint: disable=unused-argument
def empty_comment_function(source: Optional[str] = None) -> str:
return ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
try:
from websockets.client import ( # type: ignore[import-not-found,unused-ignore]
WebSocketClientProtocol,
)
from websockets.client import (
connect as ws_connect,
)
from websockets.typing import ( # type: ignore[import-not-found,unused-ignore]
Expand All @@ -29,15 +31,15 @@
from contextlib import asynccontextmanager

@asynccontextmanager # type: ignore
async def ws_connect(*args, **kwargs): # pylint: disable=unused-argument
async def ws_connect(*args, **kwargs):
raise NotImplementedError("Subscriptions require 'websockets' package.")
yield # pylint: disable=unreachable
yield

WebSocketClientProtocol = Any # type: ignore[misc,assignment,unused-ignore]
Data = Any # type: ignore[misc,assignment,unused-ignore]
Origin = Any # type: ignore[misc,assignment,unused-ignore]

def Subprotocol(*args, **kwargs): # type: ignore # pylint: disable=invalid-name
def Subprotocol(*args, **kwargs): # type: ignore # noqa: N802, N803
raise NotImplementedError("Subscriptions require 'websockets' package.")


Expand Down
Loading