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

This file was deleted.

20 changes: 10 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
name: Python CI
on:
push:

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.

The push: branches: [master] trigger was removed.

Is this intentional?

branches:
- master
pull_request:
branches:
- '**'
workflow_call:
jobs:
run_tests:
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
python-version: ['3.12']
toxenv: [django42, django52, quality]
name: ${{ matrix.toxenv }}
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

- name: Python setup
uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6.3.0
- name: Setup uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
with:
python-version: ${{ matrix.python-version }}
enable-cache: true

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

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

- name: Upload coverage to CodeCov
if: matrix.python-version == '3.12' && matrix.toxenv == 'django42'
Expand Down
71 changes: 71 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
name: Semantic Release

on:
push:
branches:
- master

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

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:
- name: Checkout
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
ref: ${{ github.ref_name }}

- name: Reset to triggered commit
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[bot]"
git_committer_email: "github-actions[bot]@users.noreply.github.com"
changelog: "false"

- name: Upload dist artifacts
if: steps.release.outputs.released == 'true'
uses: actions/upload-artifact@v4

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.

actions/upload-artifact@v4 is a floating tag. Pin to a SHA with a version comment for supply-chain security, consistent with actions/checkout and setup-uv elsewhere in this PR.

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:
- name: Download dist artifacts
uses: actions/download-artifact@v4

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.

actions/download-artifact@v4 is a floating tag. Pin to a SHA with a version comment, same as the upload step above.

with:
name: dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
6 changes: 1 addition & 5 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
include AUTHORS
include CHANGELOG.rst
include LICENSE.txt
include LICENSE.TXT
include README.rst
include requirements/base.in
include requirements/test.in
include requirements/test.txt
include requirements/constraints.txt
37 changes: 8 additions & 29 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -48,48 +48,27 @@ coverage: clean ## generate and view HTML coverage report
pytest --cov-report html
$(BROWSER) htmlcov/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
# Make sure to compile files after any other files they include!
pip-compile --upgrade --allow-unsafe --rebuild -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 --rebuild --upgrade -o requirements/base.txt requirements/base.in
pip-compile --rebuild --upgrade -o requirements/test.txt requirements/test.in
pip-compile --rebuild --upgrade -o requirements/quality.txt requirements/quality.in
pip-compile --rebuild --upgrade -o requirements/ci.txt requirements/ci.in
pip-compile --rebuild --upgrade -o requirements/dev.txt requirements/test.in requirements/quality.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 --with edx-lint edx_lint write_uv_constraints pyproject.toml
uv lock --upgrade

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

requirements: ## install development environment requirements
pip install -qr requirements/dev.txt --exists-action w
pip install -qr requirements/local.txt --exists-action w
uv sync --group dev

install: requirements

test: clean ## run tests in the current virtualenv
pip install -qr requirements/local.txt --exists-action w ## Install sample xblocks
pytest
uv run pytest

diff_cover: test
diff-cover coverage.xml

test-all: ## run tests on every supported Python/Django combination
tox -e quality
tox
uv run tox -e quality
uv run tox

validate: quality test ## run tests and quality checks

Expand Down
161 changes: 161 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
[build-system]
requires = ["setuptools>=64", "setuptools-scm>=8.0"]

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.

We had a discussion on it.
It's not a blocker.

build-backend = "setuptools.build_meta"

[project]
name = "xblock-sdk"
dynamic = ["version"]
description = "XBlock SDK"
readme = "README.rst"
license = "AGPL-3.0"
license-files = ["LICENSE.TXT"]
classifiers = [
"Development Status :: 3 - Alpha",
"Framework :: Django",
"Framework :: Django :: 4.2",
"Framework :: Django :: 5.2",
"Intended Audience :: Developers",
"Natural Language :: English",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
]
requires-python = ">=3.12"
dependencies = [
"cookiecutter",
"django>=4.2",
"fs-s3fs",
"lxml",
"requests",
"pypng",
"simplejson",
"web-fragments",
"webob",
"XBlock[django]",
]

[project.entry-points."xblock.v1"]
helloworld_demo = "sample_xblocks.basic.content:HelloWorldBlock"
allscopes_demo = "sample_xblocks.basic.content:AllScopesBlock"
html_demo = "sample_xblocks.basic.content:HtmlBlock"
sequence_demo = "sample_xblocks.basic.structure:Sequence"
vertical_demo = "sample_xblocks.basic.structure:VerticalBlock"
sidebar_demo = "sample_xblocks.basic.structure:SidebarBlock"
problem_demo = "sample_xblocks.basic.problem:ProblemBlock"
textinput_demo = "sample_xblocks.basic.problem:TextInputBlock"
equality_demo = "sample_xblocks.basic.problem:EqualityCheckerBlock"
attempts_scoreboard_demo = "sample_xblocks.basic.problem:AttemptsScoreboardBlock"
slider_demo = "sample_xblocks.basic.slider:Slider"
view_counter_demo = "sample_xblocks.basic.view_counter:ViewCounter"
thumbs = "sample_xblocks.thumbs:ThumbsBlock"
filethumbs = "sample_xblocks.filethumbs:FileThumbsBlock"
debugchild = "workbench.blocks:DebuggingChildBlock"

[tool.setuptools_scm]
version_scheme = "only-version"
local_scheme = "no-local-version"

[tool.setuptools.packages.find]
where = ["src"]

[tool.setuptools.package-data]
"sample_xblocks.basic" = ["public/**/*", "templates/**/*"]
"sample_xblocks.thumbs" = ["static/**/*"]
"sample_xblocks.filethumbs" = ["static/**/*"]
"workbench" = ["static/**/*", "templates/**/*", "test/**/*"]

[tool.setuptools.exclude-package-data]
"*" = ["tests*", "*.tests*", "spec*", "*.spec*"]

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.

The pattern "tests*" does not match directories named test/ (singular). The test dirs in this repo (workbench/test/, sample_xblocks/basic/test/) use the singular form, so they appear in the built wheel. Add "test*" and "*.test*":

"*" = ["test*", "tests*", "*.test*", "*.tests*", "spec*", "*.spec*"]


[tool.coverage.run]
branch = true
source = ["."]

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.

After the src/ move, source = ["."] measures coverage from the repo root rather than the installed packages. Use source_pkgs instead:

source_pkgs = ["workbench", "sample_xblocks"]

This ensures pytest-cov targets the installed package under src/ rather than unrelated root-level files.

omit = [
"workbench/test/*",

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.

The omit paths here (and on the next line) use the pre-src/ layout. After the move, test files live at src/workbench/test/* and src/sample_xblocks/*/test/*, so these patterns will not match and test-helper code will be included in coverage:

omit = [
    "src/workbench/test/*",
    "src/sample_xblocks/*/test/*",
    "*/migrations/*",
    "*/__pycache__/*",
    "*/settings.py",
]

"sample_xblocks/*/test/*",
"*/migrations/*",
"*/__pycache__/*",
"*/settings.py",
]

[tool.coverage.report]
show_missing = true
exclude_lines = [
"pragma: no cover",
"def __repr__",
"raise AssertionError",
"raise NotImplementedError",
"if __name__ == .__main__.:",
"if TYPE_CHECKING:",
]

[tool.coverage.html]
directory = "htmlcov"

[dependency-groups]
# To update the matrix: run `uv lock --upgrade` and add/remove Django version groups as needed.
test-base = [
"acid-xblock",
"coverage",
"ddt",
"mock",
"pytest",
"pytest-cov",
"pytest-django",
"pytest-rerunfailures",
]
test = [
{ include-group = "test-base" },
"django>=5.2,<6.0",
]
django42 = [
"django>=4.2,<5.0",
]
quality = [
{ include-group = "test" },
"edx-lint",
"isort",
"pycodestyle",
"pydocstyle",
]
doc = [
{ include-group = "test" },
"sphinx",
"sphinxcontrib-napoleon",
]
ci = [
"tox",
"tox-uv",
]
dev = [
{ include-group = "quality" },
{ include-group = "ci" },
{ include-group = "doc" },
]

[tool.uv]
package = true
# test includes Django>=5.2 and django42 includes Django>=4.2,<5.0 — they conflict.
conflicts = [
[
{ group = "test" },
{ group = "django42" },
],
]
constraint-dependencies = [
"Django<6.0",
"elasticsearch<7.14.0",
"setuptools<82.0",
]

[tool.edx_lint]
uv_constraints = [
# setuptools 82 removed pkg_resources; pyfilesystem2 (fs) still uses it
# https://setuptools.pypa.io/en/latest/history.html#v82-0-0
"setuptools<82.0",
]

[tool.semantic_release]
version_toml = []
build_command = "python -m pip install --upgrade build && SETUPTOOLS_SCM_PRETEND_VERSION=$NEW_VERSION python -m build"
allow_zero_version = true
major_on_zero = false
14 changes: 0 additions & 14 deletions requirements/base.in

This file was deleted.

Loading
Loading