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

This file was deleted.

19 changes: 10 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,34 +6,35 @@ on:
pull_request:
branches:
- '**'
workflow_call:

jobs:
run_tests:
name: Tests
runs-on: ${{ matrix.os }}
permissions:
contents: read
strategy:
matrix:
os: [ubuntu-latest]
python-version: ['3.12']
toxenv: [quality, django52-drf314, django52-drflatest]
toxenv: [quality, docs, django52-drf314, django52-drflatest]

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@1c37ad07a6a961277cf70c0d37d6f313000f5884 # v10.3.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
run: uv run tox

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

This file was deleted.

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

on:
push:
branches: [master]

jobs:
# The same aggregate a pull request has to pass, so the release runs exactly
# the checks that were required to merge -- and picks up any package added to
# ci.yml later without needing a change here.
run_ci:
uses: ./.github/workflows/ci.yml

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

run_ci calls ci.yml without secrets: inherit, so on master pushes the Codecov step runs without CODECOV_TOKEN, and it has fail_ci_if_error: true. sample-plugin and XBlock are set up the same way, so tokenless upload is probably fine, but has this been confirmed? If the upload fails, release won't run.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yes, openedx-chem has the same setup (no secrets: inherit, fail_ci_if_error: true) and the Codecov upload passed in its v2.0.1 release run.


release:
# Every package this workflow publishes has to build before we tag
# anything. The GitHub release and the PyPI uploads cannot be taken back,
# so a package that only fails to build in its publish job would leave the
# release half-finished.
needs: [run_ci]
runs-on: ubuntu-latest
if: github.ref_name == 'master'
concurrency:
group: ${{ github.workflow }}-release-${{ github.ref_name }}
cancel-in-progress: false

permissions:
contents: write

steps:
# Note: We checkout the repository at the branch that triggered the workflow.
# Python Semantic Release will automatically convert shallow clones to full clones
# if needed to ensure proper history evaluation. However, we forcefully reset the
# branch to the workflow sha because it is possible that the branch was updated
# while the workflow was running, which prevents accidentally releasing un-evaluated
# changes.
- name: Setup | Checkout Repository on Release Branch
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
ref: ${{ github.ref_name }}

- name: Setup | Force release branch to be at workflow sha
run: |
git reset --hard ${{ github.sha }}

- name: Action | Semantic Version Release
id: release
# Adjust tag with desired version if applicable.
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"
changelog: "false"
# 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"

# This repo has immutable releases enabled, which freezes a release's
# assets the moment it is published, so assets cannot be attached
# afterwards. Everything we want on the release has to be built by now
# and passed to this one command, which creates the release as a draft,
# uploads the assets, and only then publishes it:
# https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/immutable-releases
- name: Publish | 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: |
# Output the release notes to a file
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
# Creates the release as a draft, uploads the assets, and then
# publishes it -- all within this one command.
gh release create "$TAG" \
--verify-tag \
--title "$TAG" \
--notes-file "$RUNNER_TEMP/release_notes.md" \
dist/*

- name: Upload | Distribution Artifacts
uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
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:
# 1. Separate out the publish step from the github release step to run each step at
# the least amount of token privilege
# 2. Also, publishing can fail, and its better to have a separate job if you need to retry
# and it won't require reversing the release.
runs-on: ubuntu-latest
needs: release
if: github.ref_name == 'master' && needs.release.outputs.released == 'true'

permissions:
contents: read
id-token: write

steps:
- name: Setup | Download Build Artifacts
uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
id: artifact-download
with:
name: distribution-artifacts
path: dist

- name: Publish to PyPi
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
4 changes: 4 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
.. DEPRECATED: This changelog is no longer maintained. Release notes are
published only on the GitHub Releases page:
https://github.com/openedx/completion/releases

Change Log
==========

Expand Down
3 changes: 0 additions & 3 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
include CHANGELOG.rst
include LICENSE
include README.rst
include requirements/base.in
include requirements/test.in
recursive-include completion *.html *.png *.gif *js *.css *jpg *jpeg *svg *py

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The sdist grew from 60 files in 5.0.0 to 100 here. setuptools-scm adds every git-tracked file, so it now ships uv.lock, .github/, docs/, Makefile, tox.ini, pytest.ini, pylintrc, codecov.yml, catalog-info.yaml and more. Can you add excludes here?

prune .github
prune .tx
prune docs
prune htmlcov
exclude uv.lock Makefile tox.ini pytest.ini pylintrc pylintrc_tweaks codecov.yml catalog-info.yaml openedx.yaml manage.py .gitignore
global-exclude .coverage coverage.xml

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'd keep this out of the migration PR. None of the merged migrations added sdist excludes, so it fits better as a separate follow-up.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Thanks for the context! Since this PR switches to setuptools-scm and that's what pulls the extra files into the sdist, I think it'd be nice to keep parity with master here. The earlier migrations probably just missed it. Maybe we can start adding the excludes in the open and upcoming PRs, and pick up the merged repos during the backporting cycle?

include requirements/constraints.txt
41 changes: 8 additions & 33 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ help: ## display this help message
@perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}'

install:
pip install -r requirements/dev.txt
uv sync --group dev

clean: ## remove generated byte code, coverage reports, and build artifacts
find . -name '__pycache__' -exec rm -rf {} +
Expand All @@ -41,43 +41,18 @@ docs: ## generate Sphinx HTML documentation, including API docs
tox -e docs
$(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 "$(@)"

compile-requirements: export CUSTOM_COMPILE_COMMAND=make upgrade
compile-requirements: $(COMMON_CONSTRAINTS_TXT) ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in
pip install -qr requirements/pip-tools.txt
# Make sure to compile files after any other files they include!
pip-compile ${COMPILE_OPTS} --allow-unsafe --rebuild -o requirements/pip.txt requirements/pip.in
pip-compile ${COMPILE_OPTS} -o requirements/pip-tools.txt requirements/pip-tools.in
pip install -qr requirements/pip.txt
pip install -qr requirements/pip-tools.txt
pip-compile ${COMPILE_OPTS} --allow-unsafe -o requirements/base.txt requirements/base.in
pip-compile ${COMPILE_OPTS} -o requirements/test.txt requirements/test.in
pip-compile ${COMPILE_OPTS} -o requirements/doc.txt requirements/doc.in
pip-compile ${COMPILE_OPTS} --allow-unsafe -o requirements/quality.txt requirements/quality.in
pip-compile ${COMPILE_OPTS} -o requirements/ci.txt requirements/ci.in
pip-compile ${COMPILE_OPTS} -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
# Also lets tox control DRF version
sed '/^[dD]jangorestframework==/d' requirements/test.txt > requirements/test.tmp
mv requirements/test.tmp requirements/test.txt

upgrade: ## update the pip requirements files to use the latest releases satisfying our constraints
$(MAKE) compile-requirements COMPILE_OPTS="--upgrade"
compile-requirements: ## generate the uv.lock file without upgrading packages
uv lock

upgrade: ## upgrade all packages in uv.lock and sync constraints from edx-lint
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

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

test: clean ## run tests in the current virtualenv
pytest
Expand Down
4 changes: 2 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@ To run the test suite:
.. code:: bash

pip install tox
tox # to run only a single environment, do e.g. tox -e py312-django52-drflatest
tox # to run only a single environment, do e.g. tox -e django52-drflatest


To use a Django shell to test commands:

.. code:: bash

make install
make requirements
python manage.py migrate
python manage.py shell
>>> from completion.models import BlockCompletion
Expand Down
3 changes: 2 additions & 1 deletion completion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
Completion App
"""

from importlib.metadata import version

__version__ = '5.0.0'
__version__ = version("edx-completion")
16 changes: 2 additions & 14 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@


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

import django
Expand Down Expand Up @@ -70,22 +70,10 @@
# your code.
os.environ['DJANGO_SETTINGS_MODULE'] = 'completion.settings.test_settings'

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() # pylint: disable=open-builtin
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('../completion', '__init__.py')
VERSION = get_version('edx-completion')

# Configure Django for autodoc usage
django.setup()
Expand Down
Loading
Loading