Skip to content

Commit f06aef8

Browse files
authored
Merge pull request #328 from farhan/farhan/modernize-python-repo
chore: Modernize codejail to use uv and pyproject.toml
2 parents de7ae26 + 7de502c commit f06aef8

44 files changed

Lines changed: 1128 additions & 282 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.coveragerc‎

Lines changed: 0 additions & 8 deletions
This file was deleted.

‎.github/workflows/ci.yml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ on:
44
branches:
55
- master
66
pull_request:
7+
workflow_call:
78

89
jobs:
910
codejail_ci:

‎.github/workflows/pypi-release.yml‎

Lines changed: 0 additions & 33 deletions
This file was deleted.

‎.github/workflows/release.yml‎

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
name: Release
2+
3+
on:
4+
push:
5+
branches: [master]
6+
7+
jobs:
8+
run_ci:
9+
uses: ./.github/workflows/ci.yml
10+
11+
release:
12+
needs: run_ci
13+
runs-on: ubuntu-latest
14+
if: github.ref_name == 'master'
15+
concurrency:
16+
group: ${{ github.workflow }}-release-${{ github.ref_name }}
17+
cancel-in-progress: false
18+
19+
permissions:
20+
contents: write
21+
22+
steps:
23+
- name: Checkout repository
24+
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
25+
with:
26+
ref: ${{ github.ref_name }}
27+
28+
- name: Force branch to workflow sha
29+
run: git reset --hard ${{ github.sha }}
30+
31+
- name: Run Semantic Release
32+
id: release
33+
uses: python-semantic-release/python-semantic-release@9a026e9303981c866c3425723009becb2437c757 # v10.6.2
34+
with:
35+
github_token: ${{ secrets.GITHUB_TOKEN }}
36+
git_committer_name: "github-actions"
37+
git_committer_email: "actions@users.noreply.github.com"
38+
vcs_release: "false"
39+
40+
- name: Create GitHub Release with Assets
41+
if: steps.release.outputs.released == 'true'
42+
env:
43+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
RELEASE_NOTES: ${{ steps.release.outputs.release_notes }}
45+
TAG: ${{ steps.release.outputs.tag }}
46+
run: |
47+
printf '%s' "$RELEASE_NOTES" > "$RUNNER_TEMP/release_notes.md"
48+
gh release create "$TAG" \
49+
--verify-tag \
50+
--title "$TAG" \
51+
--notes-file "$RUNNER_TEMP/release_notes.md" \
52+
dist/*
53+
54+
- name: Upload distribution artifacts
55+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
56+
if: steps.release.outputs.released == 'true'
57+
with:
58+
name: distribution-artifacts
59+
path: dist
60+
if-no-files-found: error
61+
62+
outputs:
63+
released: ${{ steps.release.outputs.released || 'false' }}
64+
version: ${{ steps.release.outputs.version }}
65+
66+
publish_to_pypi:
67+
runs-on: ubuntu-latest
68+
needs: release
69+
if: github.ref_name == 'master' && needs.release.outputs.released == 'true'
70+
71+
permissions:
72+
contents: read
73+
id-token: write
74+
75+
steps:
76+
- name: Download build artifacts
77+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
78+
with:
79+
name: distribution-artifacts
80+
path: dist
81+
82+
- name: Publish to PyPI
83+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2

‎CHANGELOG.rst‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
.. DEPRECATED: This changelog is no longer maintained. Release notes are
2+
published only on the GitHub Releases page:
3+
https://github.com/openedx/codejail/releases
4+
15
Changelog
26
#########
37

‎Dockerfile‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ RUN curl -sS https://bootstrap.pypa.io/get-pip.py -o get-pip.py && \
3131
python${python_version} get-pip.py --break-system-packages && rm get-pip.py
3232
RUN pip install virtualenv --break-system-packages
3333

34+
# Install uv for dependency management (install system-wide to /usr/local/bin)
35+
RUN curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR=/usr/local/bin sh
36+
3437
# Define Environment Variables
3538
ENV CODEJAIL_GROUP=sandbox
3639
ENV CODEJAIL_SANDBOX_CALLER=ubuntu
@@ -66,16 +69,15 @@ RUN chown -R $CODEJAIL_TEST_USER:$CODEJAIL_GROUP $CODEJAIL_TEST_VENV
6669

6770
WORKDIR /codejail
6871

69-
# Clone Requirement files
70-
COPY ./requirements/sandbox.txt /codejail/requirements/sandbox.txt
71-
COPY ./requirements/testing.txt /codejail/requirements/testing.txt
72-
COPY ./requirements/tox.txt /codejail/requirements/tox.txt
72+
# Copy project files needed for dependency installation
73+
COPY pyproject.toml uv.lock /codejail/
7374

74-
# Install codejail_sandbox sandbox dependencies
75-
RUN source $CODEJAIL_TEST_VENV/bin/activate && pip install -r /codejail/requirements/sandbox.txt && deactivate
75+
# Install sandbox dependencies into the sandbox virtualenv from the
76+
# 'sandbox' dependency group
77+
RUN uv pip install --python $CODEJAIL_TEST_VENV/bin/python --no-cache-dir --group sandbox
7678

77-
# Install testing requirements in parent venv
78-
RUN pip install -r /codejail/requirements/sandbox.txt -r /codejail/requirements/testing.txt -r /codejail/requirements/tox.txt
79+
# Install CI dependencies (tox + tox-uv) into the main venv from the 'ci' group
80+
RUN uv pip install --python $VIRTUAL_ENV/bin/python --no-cache-dir --group ci
7981

8082
# Clone Codejail Repo
8183
COPY . /codejail

‎MANIFEST.in‎

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
include LICENSE.txt
2-
include README.rst
3-
include requirements/*
1+
# Exclude development, test, and documentation folders
2+
prune .github
3+
prune docs
4+
5+
# Exclude root level configuration and build files
6+
exclude Makefile
7+
exclude conftest.py
8+
exclude .gitignore
9+
exclude tox.ini
10+
11+
# Include operational files needed by the package
412
include apparmor-profiles/*
513
include sudoers-file/*
6-
include requirements/constraints.txt

‎Makefile‎

Lines changed: 11 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
test_proxy upgrade upgrade
44

55
clean:
6-
find codejail -name '*.pyc' -exec rm -f {} +
7-
find codejail -name '*.pyo' -exec rm -f {} +
8-
find codejail -name '__pycache__' -exec rm -rf {} +
6+
find src/codejail -name '*.pyc' -exec rm -f {} +
7+
find src/codejail -name '*.pyo' -exec rm -f {} +
8+
find src/codejail -name '__pycache__' -exec rm -rf {} +
99

1010

1111
test: test_no_proxy test_proxy
@@ -18,34 +18,19 @@ test_proxy:
1818
@echo "Running all tests with proxy process"
1919
CODEJAIL_PROXY=1 pytest --junitxml=reports/pytest-proxy.xml --log-level=DEBUG
2020

21-
COMMON_CONSTRAINTS_TXT=requirements/common_constraints.txt
22-
.PHONY: $(COMMON_CONSTRAINTS_TXT)
23-
$(COMMON_CONSTRAINTS_TXT):
24-
wget -O "$(@)" https://raw.githubusercontent.com/edx/edx-lint/master/edx_lint/files/common_constraints.txt || touch "$(@)"
25-
26-
upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade
27-
upgrade: $(COMMON_CONSTRAINTS_TXT)
28-
## update the requirements/*.txt files with the latest packages satisfying requirements/*.in
29-
pip install -q -r requirements/pip_tools.txt
30-
pip-compile --allow-unsafe --rebuild --annotation-style=line --upgrade -o requirements/pip_tools.txt requirements/pip_tools.in
31-
pip install -q -r requirements/pip_tools.txt
32-
pip-compile --annotation-style=line --upgrade -o requirements/tox.txt requirements/tox.in
33-
pip-compile --annotation-style=line --upgrade -o requirements/testing.txt requirements/testing.in
34-
pip-compile --annotation-style=line --upgrade -o requirements/sandbox.txt requirements/sandbox.in
35-
pip-compile --annotation-style=line --upgrade -o requirements/development.txt requirements/development.in
36-
# Handle Django via tox
37-
sed -i '/^[dD]jango==/d' requirements/testing.txt
21+
upgrade: ## update python dependencies
22+
uv run --with edx-lint edx_lint write_uv_constraints pyproject.toml
23+
uv lock --upgrade
3824

3925
quality: ## check coding style with pycodestyle and pylint
40-
pycodestyle codejail *.py
41-
isort --check-only --diff codejail *.py
42-
pylint codejail *.py
26+
pycodestyle src/codejail *.py
27+
isort --check-only --diff src/codejail *.py
28+
pylint src/codejail *.py
4329

4430
isort: ## apply automatic import sorting
45-
isort --recursive codejail *.py
31+
isort --recursive src/codejail *.py
4632

4733
requirements: dev-requirements
4834

4935
dev-requirements:
50-
pip install -r requirements/sandbox.txt
51-
pip install -r requirements/development.txt
36+
uv sync --group dev

‎codejail/__init__.py‎

Lines changed: 0 additions & 3 deletions
This file was deleted.

‎pyproject.toml‎

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
[build-system]
2+
requires = ["setuptools", "setuptools-scm>8.1"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "edx-codejail"
7+
description = "CodeJail manages execution of untrusted code in secure sandboxes. It is designed primarily for Python execution, but can be used for other languages as well."
8+
requires-python = ">=3.12"
9+
license = "Apache-2.0"
10+
license-files = ["LICENSE*"]
11+
authors = [
12+
{name = "Open edX Project", email = "oscm@openedx.org"},
13+
]
14+
classifiers = [
15+
"Development Status :: 5 - Production/Stable",
16+
"Operating System :: POSIX :: Linux",
17+
"Intended Audience :: Developers",
18+
"Programming Language :: Python",
19+
"Programming Language :: Python :: 3",
20+
"Programming Language :: Python :: 3.12",
21+
]
22+
keywords = [
23+
"Python",
24+
"edx",
25+
"codejail",
26+
]
27+
28+
dynamic = ["readme", "version"]
29+
30+
dependencies = [
31+
"six",
32+
]
33+
34+
[project.urls]
35+
Homepage = "https://github.com/openedx/codejail"
36+
Repository = "https://github.com/openedx/codejail"
37+
38+
[dependency-groups]
39+
sandbox = [
40+
"numpy",
41+
"six",
42+
]
43+
test-base = [
44+
{include-group = "sandbox"},
45+
"pylint",
46+
"pytest",
47+
"isort",
48+
"pycodestyle",
49+
]
50+
test = [
51+
{include-group = "test-base"},
52+
"Django>=5.2,<6.0",
53+
]
54+
django42 = [
55+
{include-group = "test-base"},
56+
"Django>=4.2,<5.0",
57+
]
58+
quality = [
59+
{include-group = "test"},
60+
"edx-lint",
61+
]
62+
ci = [
63+
"tox",
64+
"tox-uv",
65+
]
66+
dev = [
67+
{include-group = "quality"},
68+
{include-group = "ci"},
69+
]
70+
71+
[tool.setuptools]
72+
include-package-data = true
73+
script-files = ["memory_stress.py"]
74+
75+
[tool.setuptools.dynamic]
76+
readme = {file = ["README.rst"], content-type = "text/x-rst"}
77+
78+
[tool.setuptools.packages.find]
79+
where = ["src"]
80+
81+
[tool.setuptools.package-data]
82+
"*" = [
83+
"tests/hello.txt",
84+
]
85+
86+
[tool.semantic_release]
87+
build_command = "pip install build && SETUPTOOLS_SCM_PRETEND_VERSION=$NEW_VERSION python -m build"
88+
89+
[tool.setuptools_scm]
90+
version_scheme = 'only-version'
91+
local_scheme = 'no-local-version'
92+
fallback_version = "0.0.0.dev0"
93+
94+
[tool.uv]
95+
package = true
96+
conflicts = [
97+
[{group = "django42"}, {group = "test"}],
98+
[{group = "django42"}, {group = "quality"}],
99+
[{group = "dev"}, {group = "django42"}],
100+
]
101+
constraint-dependencies = [
102+
"Django<6.0",
103+
"elasticsearch<7.14.0",
104+
"social-auth-app-django<6.0.0",
105+
"social-auth-core<5.0.0",
106+
"pip<26.2.1",
107+
]
108+
109+
[tool.edx_lint]
110+
uv_constraints = []
111+
112+
[tool.coverage.run]
113+
branch = true
114+
source = ["codejail"]
115+
omit = [
116+
"*/tests/doit.py",
117+
]
118+
119+
[tool.coverage.report]
120+
show_missing = true
121+
122+
[tool.isort]
123+
include_trailing_comma = true
124+
indent = " "
125+
line_length = 120
126+
multi_line_output = 3

0 commit comments

Comments
 (0)