Skip to content
Open
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
7 changes: 0 additions & 7 deletions .coveragerc

This file was deleted.

21 changes: 9 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@ on:
pull_request:
branches:
- "**"
workflow_call:

@irfanuddinahmad irfanuddinahmad Aug 6, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This new workflow_call: trigger, combined with the pre-existing push: [master] trigger a few lines up (unchanged by this PR), means every push to master now runs this full matrix twice concurrently: once via the direct push trigger, once via release.yml calling this workflow as its run_tests job. Recommend dropping the push: [master] trigger now that release.yml owns that path.


jobs:
run_tests:
name: Tests
name: ${{ matrix.toxenv }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
Expand All @@ -19,21 +20,17 @@ jobs:

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: setup python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: ${{ matrix.python-version }}
enable-cache: true
python-version: "${{ matrix.python-version }}"

- name: Install pip
run: pip install -r requirements/pip.txt

- name: Install Dependencies
run: pip install -r requirements/ci.txt
- name: Install CI dependencies
run: uv sync --group ci

- name: Run Tests
env:
TOXENV: ${{ matrix.toxenv }}
run: tox
run: uv run tox -e ${{ matrix.toxenv }}

- name: Run Coverage
if: matrix.python-version == '3.12' && matrix.toxenv=='django42'
Expand Down
33 changes: 0 additions & 33 deletions .github/workflows/pypi-publish.yml

This file was deleted.

56 changes: 56 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
name: Semantic Release

on:
push:
branches: [master]

jobs:
run_tests:
uses: ./.github/workflows/ci.yml
secrets: inherit

release:
needs: run_tests
if: github.ref_name == 'master'
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-release
cancel-in-progress: false
permissions:
contents: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
ref: ${{ github.ref_name }}
- run: git reset --hard ${{ github.sha }}
- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@350c48fcb3ffcdfd2e0a235206bc2ecea6b69df0 # v10.5.3
with:
git_committer_name: "github-actions"
git_committer_email: "github-actions@github.com"
changelog: "false"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

changelog: "false" overrides the [tool.semantic_release.changelog] config this same PR carefully builds in pyproject.toml (mode = "update", matching insertion_flag) -- the action-level flag wins, silently disabling changelog generation entirely despite the config looking correct. This is the exact incident class that already caused real CHANGELOG.rst content loss in a sibling repo in this effort.

- name: Upload dist
if: steps.release.outputs.released == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
with:
name: dist
path: dist/
outputs:
released: ${{ steps.release.outputs.released }}
version: ${{ steps.release.outputs.version }}

publish_to_pypi:
needs: release
if: needs.release.outputs.released == 'true'
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
with:
name: dist
path: dist/
- uses: pypa/gh-action-pypi-publish@release/v1
6 changes: 5 additions & 1 deletion .readthedocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ build:
os: ubuntu-lts-latest
tools:
python: "3.12"
jobs:
post_install:
- pip install uv && uv export --group doc --no-hashes | pip install -r /dev/stdin

python:
install:
- requirements: requirements/doc.txt
- method: pip
path: .
2 changes: 2 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ Change Log

.. There should always be an "Unreleased" section for changes pending release.

.. changelog-insertion-marker

Unreleased
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
47 changes: 14 additions & 33 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,51 +34,32 @@ coverage: clean ## generate and view HTML coverage report
$(BROWSER) htmlcov/index.html

docs: ## generate Sphinx HTML documentation, including API docs
tox -e docs
uv run --group doc doc8 --ignore-path docs/_build README.rst docs
uv run --group doc sphinx-build -b html docs docs/_build/html
$(BROWSER) docs/_build/html/index.html

COMMON_CONSTRAINTS_TXT=requirements/common_constraints.txt
.PHONY: $(COMMON_CONSTRAINTS_TXT)
$(COMMON_CONSTRAINTS_TXT):
wget -O "$(@)" https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt || touch "$(@)"

upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade
upgrade: $(COMMON_CONSTRAINTS_TXT) # update the requirements/*.txt files with the latest packages satisfying requirements/*.in
pip install -qr requirements/pip-tools.txt
pip install -qr requirements/pip.txt
pip-compile --upgrade --allow-unsafe -o requirements/pip.txt requirements/pip.in
pip-compile --upgrade -o requirements/pip-tools.txt requirements/pip-tools.in
pip install -qr requirements/pip.txt
pip install -qr requirements/pip-tools.txt
pip-compile --upgrade -o requirements/base.txt requirements/base.in
pip-compile --upgrade -o requirements/django.txt requirements/django.in
pip-compile --upgrade -o requirements/test.txt requirements/test.in
pip-compile --upgrade -o requirements/doc.txt requirements/doc.in
pip-compile --upgrade -o requirements/quality.txt requirements/quality.in
pip-compile --upgrade -o requirements/ci.txt requirements/ci.in
pip-compile --upgrade -o requirements/dev.txt requirements/dev.in
# Let tox control the Django version for tests
sed '/^[dD]jango==/d' requirements/test.txt > requirements/test.tmp
mv requirements/test.tmp requirements/test.txt
upgrade: ## update uv.lock and regenerate uv constraint-dependencies
uv run --group quality edx_lint write_uv_constraints pyproject.toml
uv lock --upgrade

quality: ## check coding style with pycodestyle and pylint
tox -e quality
uv run --group quality pylint src/code_annotations tests test_utils
uv run --group quality pycodestyle src/code_annotations tests
uv run --group quality pydocstyle src/code_annotations tests
uv run --group quality isort --check-only --diff tests test_utils src/code_annotations

requirements: ## install development environment requirements
pip install -qr requirements/pip.txt
pip install -qr requirements/pip-tools.txt
pip-sync requirements/dev.txt requirements/test.txt requirements/private.*
pip install -e .
uv sync --group dev

test: clean ## run tests in the current virtualenv
pytest
uv run --group test python -Wd -m pytest

diff_cover: test ## find diff lines that need test coverage
diff-cover coverage.xml

test-all: ## run tests on every supported Python
tox -e quality
tox
test-all: ## run tests on every supported Django version
uv run --group django42 python -Wd -m pytest
uv run --group test python -Wd -m pytest

validate: quality test ## run tests and quality checks

Expand Down
24 changes: 4 additions & 20 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,16 @@
"""


import io
import os
import re
import sys
from datetime import datetime
from importlib.metadata import version as get_version
from subprocess import check_call




def get_version(*file_paths):
"""
Extract the version string from the file at the given relative path fragments.
"""
filename = os.path.join(os.path.dirname(__file__), *file_paths)
version_file = open(filename).read()
version_match = re.search(r"^__version__ = ['\"]([^'\"]*)['\"]", version_file, re.M)
if version_match:
return version_match.group(1)
raise RuntimeError('Unable to find version string.')


REPO_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(REPO_ROOT)

VERSION = get_version('../code_annotations', '__init__.py')
VERSION = get_version("code-annotations")

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
Expand Down Expand Up @@ -518,8 +502,8 @@ def on_init(app): # pylint: disable=unused-argument
# If we are, assemble the path manually
bin_path = os.path.abspath(os.path.join(sys.prefix, 'bin'))
apidoc_path = os.path.join(bin_path, apidoc_path)
check_call([apidoc_path, '-o', docs_path, os.path.join(root_path, 'code_annotations'),
os.path.join(root_path, 'code_annotations/migrations')])
check_call([apidoc_path, '-o', docs_path, os.path.join(root_path, 'src', 'code_annotations'),
os.path.join(root_path, 'src', 'code_annotations', 'migrations')])


def setup(app):
Expand Down
Loading