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
13 changes: 0 additions & 13 deletions .coveragerc

This file was deleted.

39 changes: 22 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ on:
pull_request:
branches:
- "**"
workflow_call:

jobs:
run_tests:
name: tests
name: ${{ matrix.toxenv }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-24.04]
python-version: ["3.12"]
toxenv: [quality, docs, pii_check, django52]
os:
- ubuntu-24.04
python-version:
- "3.12"
toxenv:
- quality
- docs
- pii_check
- py
permissions:
# Gives the action the necessary permissions for publishing new
# comments in pull requests.
Expand All @@ -26,25 +33,23 @@ jobs:
contents: write

steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: setup python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1

- name: Install uv
uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
with:
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 --locked --group ci

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

- name: Run coverage
if: matrix.python-version == '3.12' && matrix.toxenv == 'django42'
if: matrix.python-version == '3.12' && matrix.toxenv == 'py'
uses: py-cov-action/python-coverage-comment-action@a05be3d2e8a6272d3ef5fb2840ab20368bb2eb71 # v3
with:
GITHUB_TOKEN: ${{ github.token }}
Expand Down
30 changes: 0 additions & 30 deletions .github/workflows/pypi-publish.yml

This file was deleted.

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

on:
push:
branches: [main]

jobs:
run_ci:
uses: ./.github/workflows/ci.yml

release:
needs: run_ci
runs-on: ubuntu-latest
if: github.ref_name == 'main'
concurrency:
group: ${{ github.workflow }}-release-${{ github.ref_name }}
cancel-in-progress: false

permissions:
contents: write

steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.ref_name }}

- name: Force branch to workflow sha
run: git reset --hard ${{ github.sha }}

- name: Run Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@b700dbeb1f431a0fcc30a79f3f0869407fe07278 # v10.7.0
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
git_committer_name: "github-actions"
git_committer_email: "actions@users.noreply.github.com"
# Commit, tag, push and build, but don't create the GitHub release.
# We create it ourselves in the next step so that the distributions
# are attached before the release is published. See that step for why.
vcs_release: "false"
# Release notes live only on the GitHub Release page; no changelog file.
changelog: "false"

# The openedx org has immutable releases enabled, which freezes a release's
# assets the moment it is published, so assets cannot be attached
# afterwards. `gh release create` handles this by creating the release as a
# draft, uploading the assets, and only then publishing it:
# https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
- name: Create GitHub Release with Assets
if: steps.release.outputs.released == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Reuse the release notes python-semantic-release generated for us.
RELEASE_NOTES: ${{ steps.release.outputs.release_notes }}
TAG: ${{ steps.release.outputs.tag }}
run: |
# Write the release notes to a file so arbitrary content (backticks,
# $(...), quotes) passes through unexpanded.
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
# Create the release as a draft, attach the dists, then publish.
gh release create "$TAG" \
--verify-tag \
--title "$TAG" \
--notes-file "$RUNNER_TEMP/release_notes.md" \
dist/*

- name: Upload distribution artifacts
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: steps.release.outputs.released == 'true'
with:
name: distribution-artifacts
path: dist
if-no-files-found: error

outputs:
released: ${{ steps.release.outputs.released || 'false' }}
version: ${{ steps.release.outputs.version }}

publish_to_pypi:
runs-on: ubuntu-latest
needs: release
if: github.ref_name == 'main' && needs.release.outputs.released == 'true'

permissions:
contents: read
id-token: write # Required for OIDC trusted publishing

steps:
- name: Download build artifacts
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: distribution-artifacts
path: dist

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
11 changes: 4 additions & 7 deletions .readthedocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@ build:

python:
install:

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
install:
# `uv sync` against the committed uv.lock, so the docs build against the
# same pinned versions as CI -- and inherits the minimum release age
# recorded in the lock. This used to be `requirements: requirements/doc.txt`,
# which stopped existing when the repo moved to uv.lock.
- method: uv
command: sync
groups:
- doc

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

good catch, fixed

- requirements: requirements/doc.txt

# This will pip install this repo into the python environment
# if you are using this in a repo that is not pip installable
# then you should remove the following two lines.
- method: pip
path: .
- method: uv
command: sync
groups:
- doc
15 changes: 10 additions & 5 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
include LICENSE.txt
include README.rst
include requirements/base.in
include requirements/constraints.txt
recursive-include platform_plugin_aspects *.html *.png *.gif *.js *.css *.jpg *.jpeg *.svg
# Exclude development, test, and documentation folders
prune .github
prune docs
prune tests

# Exclude root level configuration and build files
exclude Makefile
exclude conftest.py
exclude .gitignore
exclude tox.ini
48 changes: 13 additions & 35 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -32,40 +32,18 @@ docs: ## generate Sphinx HTML documentation, including API docs
tox -e docs
$(BROWSER)docs/_build/html/index.html

# Define PIP_COMPILE_OPTS=-v to get more information during make upgrade.
PIP_COMPILE = pip-compile --upgrade $(PIP_COMPILE_OPTS)

upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade
upgrade: ## 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
# Make sure to compile files after any other files they include!
$(PIP_COMPILE) --allow-unsafe -o requirements/pip.txt requirements/pip.in
$(PIP_COMPILE) -o requirements/pip-tools.txt requirements/pip-tools.in
pip install -qr requirements/pip.txt
pip install -qr requirements/pip-tools.txt
$(PIP_COMPILE) -o requirements/base.txt requirements/base.in
$(PIP_COMPILE) -o requirements/test.txt requirements/test.in
$(PIP_COMPILE) -o requirements/doc.txt requirements/doc.in
$(PIP_COMPILE) -o requirements/quality.txt requirements/quality.in
$(PIP_COMPILE) -o requirements/ci.txt requirements/ci.in
$(PIP_COMPILE) -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 python dependencies
uv run --with edx-lint edx_lint write_uv_constraints pyproject.toml
uv lock --upgrade

quality: ## check coding style with pycodestyle and pylint
tox -e quality

pii_check: ## check for PII annotations on all Django models
tox -e pii_check

piptools: ## install pinned version of pip-compile and pip-sync
pip install -r requirements/pip.txt
pip install -r requirements/pip-tools.txt

requirements: clean_tox piptools ## install development environment requirements
pip-sync -q requirements/dev.txt requirements/private.*
requirements: ## install development environment requirements
uv sync --group dev

test: clean ## run tests in the current virtualenv
pytest
Expand All @@ -74,7 +52,7 @@ diff_cover: test ## find diff lines that need test coverage
diff-cover coverage.xml

format:
isort platform_plugin_aspects
isort src/platform_plugin_aspects
black .

test-all: quality pii_check ## run tests on every supported Python/Django combination
Expand All @@ -90,23 +68,23 @@ selfcheck: ## check that the Makefile is well-formed

extract_translations: ## extract strings to be translated, outputting .mo files
rm -rf docs/_build
cd platform_plugin_aspects && django-admin makemessages -l en -v1 -d django
cd platform_plugin_aspects && django-admin makemessages -l en -v1 -d djangojs
cd src/platform_plugin_aspects && django-admin makemessages -l en -v1 -d django
cd src/platform_plugin_aspects && django-admin makemessages -l en -v1 -d djangojs

compile_translations: ## compile translation files, outputting .po files for each supported language
cd platform_plugin_aspects && i18n_tool generate
cd src/platform_plugin_aspects && i18n_tool generate

detect_changed_source_translations:
cd platform_plugin_aspects && i18n_tool changed
cd src/platform_plugin_aspects && i18n_tool changed

ifeq ($(OPENEDX_ATLAS_PULL),)
pull_translations: ## Pull translations from Transifex
tx pull -t -a -f --mode reviewed --minimum-perc=1
else
# Experimental: OEP-58 Pulls translations using atlas
pull_translations:
find platform_plugin_aspects/conf/locale -mindepth 1 -maxdepth 1 -type d -exec rm -r {} \;
atlas pull $(OPENEDX_ATLAS_ARGS) translations/platform-plugin-aspects/platform_plugin_aspects/conf/locale:platform_plugin_aspects/conf/locale
find src/platform_plugin_aspects/conf/locale -mindepth 1 -maxdepth 1 -type d -exec rm -r {} \;
atlas pull $(OPENEDX_ATLAS_ARGS) translations/platform-plugin-aspects/platform_plugin_aspects/conf/locale:src/platform_plugin_aspects/conf/locale
python manage.py compilemessages

@echo "Translations have been pulled via Atlas and compiled."
Expand All @@ -116,7 +94,7 @@ push_translations: ## push source translation files (.po) from Transifex
tx push -s

dummy_translations: ## generate dummy translation (.po) files
cd platform_plugin_aspects && i18n_tool dummy
cd src/platform_plugin_aspects && i18n_tool dummy

build_dummy_translations: extract_translations dummy_translations compile_translations ## generate and compile dummy translation files

Expand Down
25 changes: 4 additions & 21 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,34 +13,17 @@
"""

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

from django import setup as django_setup


def get_version(*file_paths):
"""
Extract the version string from the file.

Input:
- file_paths: relative path fragments to file with
version string
"""
filename = os.path.join(os.path.dirname(__file__), *file_paths)
version_file = open(filename, encoding="utf8").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("../platform_plugin_aspects", "__init__.py")
VERSION = version("platform-plugin-aspects")
# Configure Django for autodoc usage
os.environ["DJANGO_SETTINGS_MODULE"] = "test_settings"
django_setup()
Expand Down Expand Up @@ -555,8 +538,8 @@ def on_init(app): # pylint: disable=unused-argument
apidoc_path,
"-o",
docs_path,
os.path.join(root_path, "platform_plugin_aspects"),
os.path.join(root_path, "platform_plugin_aspects/migrations"),
os.path.join(root_path, "src", "platform_plugin_aspects"),
os.path.join(root_path, "src", "platform_plugin_aspects/migrations"),
]
)

Expand Down
Loading