Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
61dfda2
refactor: move package to src/ layout
irfanuddinahmad Jul 28, 2026
aa7ed88
feat: consolidate package metadata into pyproject.toml
irfanuddinahmad Jul 28, 2026
6c9f41d
feat: switch dependency management from pip-compile to uv
irfanuddinahmad Jul 28, 2026
a36fa63
feat: add semantic-release and OIDC PyPI publish workflow
irfanuddinahmad Jul 28, 2026
8b8ae3a
feat: enable python-semantic-release changelog automation
irfanuddinahmad Jul 30, 2026
2bac59f
docs: remove obsolete manual version/changelog checklist items
irfanuddinahmad Jul 30, 2026
314afe1
docs: remove stale manual tag/PyPI-verification steps from PR template
irfanuddinahmad Jul 30, 2026
1ac306b
Merge remote-tracking branch 'origin/master' into irfanuddinahmad/mod…
Aug 11, 2026
e0edee6
fix: disable python-semantic-release changelog generation
Aug 19, 2026
3766508
fix: drop tox from Makefile's quality target
Aug 24, 2026
3aceddb
fix: create GitHub release with assets attached, not after publish
irfanuddinahmad Aug 27, 2026
8ca1061
fix: pin release.yml actions to sample-plugin gold-standard SHAs
irfanuddinahmad Sep 2, 2026
f218295
fix: drop unneeded fetch-depth: 0 from ci.yml checkout
irfanuddinahmad Sep 2, 2026
b262bd8
fix: add missing contents:read permission to publish_to_pypi job
irfanuddinahmad Sep 2, 2026
b5139fc
fix: remove unnecessary try/except around __version__ (not present pr…
irfanuddinahmad Sep 9, 2026
683ae7c
fix: update author to Open edX Project convention
irfanuddinahmad Sep 9, 2026
2eb9b0b
fix: remove fail-fast: false (not present pre-migration)
irfanuddinahmad Sep 9, 2026
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
5 changes: 0 additions & 5 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,8 @@ Describe in a couple of sentences what this PR adds
**Merge checklist:**
- [ ] All reviewers approved
- [ ] CI build is green
- [ ] Version bump if needed
- [ ] Changelog record added
- [ ] Documentation updated (not only docstrings)
- [ ] Commits are squashed

**Post merge:**
- [ ] Create a tag
- [ ] Check new version is pushed to PyPi after tag-triggered build is
finished.
- [ ] Delete working branch (if not needed anymore)
31 changes: 14 additions & 17 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
name: Python CI

on:
push:
branches: [master]
workflow_call:
pull_request:
branches:
- '**'
- '**'

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

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

- name: Install uv
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.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 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=='django52'
if: matrix.python-version == '3.12' && matrix.toxenv == 'django52'
uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
34 changes: 0 additions & 34 deletions .github/workflows/pypi-publish.yml

This file was deleted.

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

on:
push:
branches: [master]

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

release:
runs-on: ubuntu-latest
needs: run_tests
if: github.ref_name == 'master'
concurrency:
group: ${{ github.workflow }}-release-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: write
outputs:
released: ${{ steps.release.outputs.released || 'false' }}
version: ${{ steps.release.outputs.version }}

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

- run: git reset --hard ${{ github.sha }}

- name: Python Semantic Release
id: release
uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
with:
github_token: ${{ secrets.OPENEDX_SEMANTIC_RELEASE_GITHUB_TOKEN }}
git_committer_name: "github-actions"
git_committer_email: "github-actions@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. `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: Publish | Create GitHub Release with Assets
if: steps.release.outputs.released == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
RELEASE_NOTES: ${{ steps.release.outputs.release_notes }}
TAG: ${{ steps.release.outputs.tag }}
run: |
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
gh release create "$TAG" \
--verify-tag \
--title "$TAG" \
--notes-file "$RUNNER_TEMP/release_notes.md" \
dist/*

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

publish_to_pypi:
runs-on: ubuntu-latest
needs: release
if: github.ref_name == 'master' && needs.release.outputs.released == 'true'
permissions:
contents: read
id-token: write

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

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
3 changes: 1 addition & 2 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
include *.rst LICENSE.txt AUTHORS
include requirements/base.in
include requirements/constraints.txt
recursive-include src/auth_backends *.html *.png *.gif *js *.css *jpg *jpeg *svg *py
42 changes: 8 additions & 34 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,45 +6,19 @@ clean:
find . -name '*.pyc' -delete

quality:
tox -e quality

uv sync --group quality
uv run pycodestyle --config=.pep8 src/auth_backends
uv run pylint --rcfile=pylintrc src/auth_backends

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

test:
tox

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


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 "$(@)"
uv run tox

upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade
upgrade: $(COMMON_CONSTRAINTS_TXT) ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in
sed 's/pyjwt\[crypto\]<2.0.0//g' requirements/common_constraints.txt > requirements/common_constraints.tmp
mv requirements/common_constraints.tmp requirements/common_constraints.txt
sed 's/social-auth-core<4.0.3//g' requirements/common_constraints.txt > requirements/common_constraints.tmp
mv requirements/common_constraints.tmp requirements/common_constraints.txt
pip install -qr requirements/pip-tools.txt
# Make sure to compile files after any other files they include!
$(PIP_COMPILE) --allow-unsafe --rebuild -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/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 the uv.lock to use the latest releases satisfying our constraints
uv run --with edx-lint edx_lint write_uv_constraints pyproject.toml
uv lock --upgrade

check_keywords: ## Scan the Django models in all installed apps in this project for restricted field names
python manage.py check_reserved_keywords --override_file db_keyword_overrides.yml
129 changes: 129 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
[build-system]
requires = ["setuptools>=64", "setuptools-scm>=8.0"]
build-backend = "setuptools.build_meta"

[project]
name = "edx-auth-backends"
description = "Custom edX authentication backends and pipeline steps"
readme = "README.rst"
license = "AGPL-3.0"
license-files = ["LICENSE.txt"]
requires-python = ">=3.12"
authors = [
{name = "Open edX Project", email = "oscm@openedx.org"},
]
keywords = ["authentication", "edx"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Environment :: Web Environment",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Framework :: Django",
"Framework :: Django :: 5.2",
"Topic :: Internet",
]
dynamic = ["version"]
dependencies = [
"django>=5.2,<6.0",
"edx-django-utils",
"edx-toggles",
"pyjwt[crypto]>=2.1.0",
"six",
"social-auth-app-django",
"social-auth-core",
]

[project.urls]
Homepage = "https://github.com/openedx/auth-backends"

[dependency-groups]
# Base test packages, no version pins - let uv.lock handle it
test-base = [
"coverage",
"ddt",
"edx-django-release-util",
"httpretty",
"pycryptodomex",
"pytest-cov",
"pytest-django",
"responses",
"typing_extensions",
"unittest2",
]
test = [
{include-group = "test-base"},
"django>=5.2,<5.3",
]
quality = [
{include-group = "test"},
"edx-lint",
"pycodestyle",
"pylint",
]
# Minimal CI group: just what's needed to invoke tox
ci = [
"tox",
"tox-uv",
]
dev = [
{include-group = "quality"},
{include-group = "ci"},
]

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

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

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

[tool.uv]
package = true

# DO NOT EDIT constraint-dependencies DIRECTLY.
# This list is managed by `edx_lint write_uv_constraints`
# and will be overwritten the next time `make upgrade` is run.
# - GLOBAL constraints: edit edx_lint/files/common_constraints.txt
# - REPO-SPECIFIC constraints: edit [tool.edx_lint].uv_constraints in this file
constraint-dependencies = [
"Django<6.0",
"elasticsearch<7.14.0",
]

[tool.edx_lint]
uv_constraints = []

[tool.semantic_release]
build_command = "python -m pip install --upgrade build && SETUPTOOLS_SCM_PRETEND_VERSION=$NEW_VERSION python -m build"
major_on_zero = false
allow_zero_version = true
tag_format = "v{version}"

[tool.coverage.run]
branch = true
source = ["src/auth_backends"]
omit = [
"*/tests/*",
"*/migrations/*",
"*/__pycache__/*",
"*/settings.py",
]

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

[tool.coverage.html]
directory = "htmlcov"
2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[pytest]
DJANGO_SETTINGS_MODULE=test_settings
addopts = --cov auth_backends --cov-report term-missing --cov-report xml
testpaths = auth_backends/tests
testpaths = src/auth_backends/tests
Loading