Skip to content

Commit

Permalink
Update Dockerfile & CI workflows to use Ubuntu 24.04 and Python 3.12 (#…
Browse files Browse the repository at this point in the history
…397)

* fix: Updates the Dockerfile to use Ubuntu 24.04 and Python 3.12

* fix: Replaces the deprecated docker-compose command with docker compose

* fix: Upgrades Ubuntu to 24.04 in the CI, Docker-publish, and PyPI-publish workflows

* fix: replaces pkg_resources with importlib.resources in cookiecutter
  • Loading branch information
irtazaakram authored Sep 4, 2024
1 parent 5fa9b3c commit fee0ef7
Show file tree
Hide file tree
Showing 25 changed files with 69 additions and 71 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ on:
- '**'
jobs:
run_tests:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
strategy:
matrix:
os: [ubuntu-20.04]
python-version: ['3.11', '3.12']
toxenv: [django42]
steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/docker-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ on:
- master
jobs:
push:
runs-on: ubuntu-latest
runs-on: ubuntu-24.04
if: github.event_name == 'push'

steps:
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:
jobs:

push:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04

steps:
- name: Checkout
Expand Down
3 changes: 3 additions & 0 deletions .isort.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ known_first_party =
workbench
sample_xblocks
sections = FUTURE,STDLIB,THIRDPARTY,DJANGO,DJANGOAPP,EDX,FIRSTPARTY,LOCALFOLDER
known_djangoapp =
workbench
sample_xblocks
6 changes: 6 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ Change history for XBlock SDK

These are notable changes in XBlock.

0.13.0 - 2024-08-28
-------------------

* upgraded to Ubuntu 24.04 and Python 3.12
* replaced deprecated docker-compose command with docker compose

0.12.0 - 2024-05-30
------------------
* dropped python 3.8 support
Expand Down
38 changes: 19 additions & 19 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
FROM edxops/focal-common:latest
FROM ubuntu:noble

RUN apt-get update && apt-get install -y \
gettext \
lib32z1-dev \
zlib1g-dev \
libjpeg62-dev \
libxslt1-dev \
zlib1g-dev \
python3 \
python3-dev \
python3-venv \
python3-pip && \
pip3 install --upgrade pip setuptools && \
rm -rf /var/lib/apt/lists/*
python3.12 \
python3.12-dev \
python3.12-venv \
curl \
make \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY . /usr/local/src/xblock-sdk
WORKDIR /usr/local/src/xblock-sdk

ENV VIRTUAL_ENV=/venvs/xblock-sdk
RUN python3.11 -m venv $VIRTUAL_ENV
RUN python3.12 -m venv $VIRTUAL_ENV
ENV PATH="$VIRTUAL_ENV/bin:$PATH"

RUN pip install --upgrade pip && pip install -r /usr/local/src/xblock-sdk/requirements/dev.txt

RUN curl -sL https://deb.nodesource.com/setup_14.x -o /tmp/nodejs-setup && \
/bin/bash /tmp/nodejs-setup && \
RUN curl -sL https://deb.nodesource.com/setup_22.x -o /tmp/nodejs-setup && \
bash /tmp/nodejs-setup && \
rm /tmp/nodejs-setup && \
apt-get -y install nodejs && \
echo $PYTHONPATH && \
make install
apt-get install -y nodejs

RUN pip install --upgrade pip setuptools
RUN make install

EXPOSE 8000
ENTRYPOINT ["python", "manage.py"]
CMD ["runserver", "0.0.0.0:8000"]

ENTRYPOINT ["bash", "-c", "python manage.py migrate && exec python manage.py runserver 0.0.0.0:8000"]
10 changes: 5 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -97,20 +97,20 @@ selfcheck: ## check that the Makefile is well-formed
@echo "The Makefile is well-formed."

docker_build:
docker-compose build
docker compose build

# devstack-themed shortcuts
dev.up: # Starts all containers
docker-compose up -d
docker compose up -d

dev.up.build:
docker-compose up -d --build
docker compose up -d --build

dev.down: # Kills containers and all of their data that isn't in volumes
docker-compose down
docker compose down

dev.stop: # Stops containers so they can be restarted
docker-compose stop
docker compose stop

app-shell: # Run bash in the container as root
docker exec -u 0 -it edx.devstack.xblock-sdk bash
Expand Down
23 changes: 8 additions & 15 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Locally
Docker
~~~~~~

Alternatively, you can build and run the xblock-sdk in Docker (we are using docker-compose which
Alternatively, you can build and run the xblock-sdk in Docker (we are using docker compose which
can be installed as explained at https://docs.docker.com/compose/install/)

After cloning this repository locally, go into the repository directory and build the Docker image::
Expand All @@ -74,43 +74,36 @@ After cloning this repository locally, go into the repository directory and buil

or manually run

$ docker-compose build
$ docker compose build

You can then run the locally-built version using the following command::

$ make dev.up

or manually run::

$ docker-compose up -d
$ docker compose up -d

and stop the container (without removing data) by::
You should now be able to access the XBlock SDK environment in your browser at http://localhost:8000

To stop the container (without removing data) by::

$ make dev.stop

or manually run::

$ docker-compose stop
$ docker compose stop

Note, using::

$ make dev.down

or::

$ docker-compose down
$ docker compose down

will shut down the container and delete non-persistent data.

On the first startup run the following command to create the SQLite database.
(Otherwise you will get an error no such table: workbench_xblockstate.)

Command::

$ docker container exec -it edx.devstack.xblock-sdk python3.11 manage.py migrate

You should now be able to access the XBlock SDK environment in your browser at http://localhost:8000

You can open a bash shell in the running container by using::

$ make app-shell
Expand Down
1 change: 0 additions & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
version: '3.5'
services:
xblock_sdk:
image: openedx/xblock-sdk
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""TO-DO: Write a description of what this XBlock is."""

import pkg_resources
from importlib.resources import files

from web_fragments.fragment import Fragment
from xblock.core import XBlock
from xblock.fields import Integer, Scope
Expand All @@ -22,8 +23,7 @@ class {{cookiecutter.class_name}}(XBlock):

def resource_string(self, path):
"""Handy helper for getting resources from our kit."""
data = pkg_resources.resource_string(__name__, path)
return data.decode("utf8")
return files(__package__).joinpath(path).read_text(encoding="utf-8")

# TO-DO: change this view to display your data your own way.
def student_view(self, context=None):
Expand Down
7 changes: 4 additions & 3 deletions pylintrc
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
# SERIOUSLY.
#
# ------------------------------
# Generated by edx-lint version: 5.2.5
# Generated by edx-lint version: 5.4.0
# ------------------------------
[MASTER]
ignore = migrations
Expand Down Expand Up @@ -259,6 +259,7 @@ enable =
useless-suppression,
disable =
bad-indentation,
broad-exception-raised,
consider-using-f-string,
duplicate-code,
file-ignored,
Expand Down Expand Up @@ -380,6 +381,6 @@ ext-import-graph =
int-import-graph =

[EXCEPTIONS]
overgeneral-exceptions = Exception
overgeneral-exceptions = builtins.Exception

# 15f4c0e4571a74bff869eddc0b2e573520a58d0c
# 80dd86efa4e64209cd8e26c39b1b42ccdcb57351
1 change: 0 additions & 1 deletion requirements/constraints.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@

# Common constraints for edx repos
-c common_constraints.txt
backports.zoneinfo;python_version<"3.9"
2 changes: 1 addition & 1 deletion sample_xblocks/basic/content.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ def fallback_view(self, view_name, context=None): # pylint: disable=W0613
value=getattr(self, field_name),
help=field.help
)
for field_name, field in self.fields.items() # pylint: disable=no-member
for field_name, field in self.fields.items()
if field_name not in ["name", "parent", "tags"]
]

Expand Down
6 changes: 3 additions & 3 deletions sample_xblocks/basic/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def student_view(self, context=None):
named_child_frags = []
# self.children is an attribute obtained from ChildrenModelMetaclass, so disable the
# static pylint checking warning about this.
for child_id in self.children: # pylint: disable=E1101
for child_id in self.children:
child = self.runtime.get_block(child_id)
frag = self.runtime.render_child(child, "problem_view", context)
result.add_fragment_resources(frag)
Expand Down Expand Up @@ -175,7 +175,7 @@ def check(self, submissions, suffix=''): # pylint: disable=unused-argument
child_map = {}
# self.children is an attribute obtained from ChildrenModelMetaclass, so disable the
# static pylint checking warning about this.
for child_id in self.children: # pylint: disable=E1101
for child_id in self.children:
child = self.runtime.get_block(child_id)
if child.name:
child_map[child.name] = child
Expand Down Expand Up @@ -334,7 +334,7 @@ def set_arguments_from_xml(self, node):
# pylint: disable=no-member, useless-suppression, deprecated-method
argspec = inspect.getfullargspec(self.check)
else:
argspec = inspect.getargspec(self.check) # pylint: disable=deprecated-method
argspec = inspect.getargspec(self.check) # pylint: disable=no-member
arguments = {}
for arg in argspec.args[1:]:
arguments[arg] = node.attrib.pop(arg)
Expand Down
2 changes: 1 addition & 1 deletion sample_xblocks/filethumbs/filethumbs.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
"""

import importlib.resources
import json
import logging

import importlib.resources
import png
from web_fragments.fragment import Fragment
from xblock.core import XBlock
Expand Down
4 changes: 2 additions & 2 deletions sample_xblocks/filethumbs/static/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# XBlock Static Files

An XBlock can load resources from its package using Python's
[pkg_resources](http://pythonhosted.org/distribute/pkg_resources.html).
[importlib.resources](https://docs.python.org/3/library/importlib.resources.html).

We use a directory structure with folders for `css`, `html`, and `js`
files. However, this structure is not mandatory. Each XBlock can
choose its directory structure, as long as it specifies the correct
paths to `pkg_resources`.
paths to `importlib.resources`.

We include unit tests for JavaScript in the `js` folder. See `js/README.md`
for details on how to run these tests.
4 changes: 2 additions & 2 deletions sample_xblocks/thumbs/static/README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# XBlock Static Files

An XBlock can load resources from its package using Python's
[pkg_resources](http://pythonhosted.org/distribute/pkg_resources.html).
[importlib.resources](https://docs.python.org/3/library/importlib.resources.html).

We use a directory structure with folders for `css`, `html`, and `js`
files. However, this structure is not mandatory. Each XBlock can
choose its directory structure, as long as it specifies the correct
paths to `pkg_resources`.
paths to `importlib.resources`.

We include unit tests for JavaScript in the `js` folder. See `js/README.md`
for details on how to run these tests.
2 changes: 1 addition & 1 deletion sample_xblocks/thumbs/thumbs.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
"""An XBlock providing thumbs-up/thumbs-down voting."""

import importlib.resources
import logging

import importlib.resources
from web_fragments.fragment import Fragment
from xblock.core import XBlock, XBlockAside
from xblock.fields import Boolean, Integer, Scope
Expand Down
3 changes: 1 addition & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,7 @@ def get_version(*file_paths):
classifiers=[
'Development Status :: 3 - Alpha',
'Framework :: Django',
'Framework :: Django :: 3.2',
'Framework :: Django :: 4.0',
'Framework :: Django :: 4.2',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)',
'Natural Language :: English',
Expand Down
2 changes: 1 addition & 1 deletion tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ deps =
-r{toxinidir}/requirements/quality.txt
commands =
pylint workbench sample_xblocks
isort --check-only .
isort --check-only workbench sample_xblocks
3 changes: 2 additions & 1 deletion workbench/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# pylint: disable=django-not-configured
"""
Provide a djangoapp for XBlock development
"""

__version__ = '0.12.0'
__version__ = '0.13.0'
2 changes: 0 additions & 2 deletions workbench/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,3 @@ class XBlockStateAdmin(admin.ModelAdmin):
readonly_fields = [
'scope', 'scope_id', 'scenario', 'tag', 'user_id', 'created'
]


2 changes: 1 addition & 1 deletion workbench/scenarios.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def add_class_scenarios(class_name, cls, fail_silently=True):
scname = "%s.%d" % (class_name, i)
try:
add_xml_scenario(scname, desc, xml)
except Exception: # pylint:disable=broad-except
except Exception: # pylint: disable=broad-exception-caught
# don't allow a single bad scenario to block the whole workbench
if fail_silently:
log.warning("Cannot load %s", desc, exc_info=True)
Expand Down
4 changes: 2 additions & 2 deletions workbench/test/test_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ def student_view(self, context=None): # pylint: disable=W0613
]
urls = []
for args in all_args:
thirdparty = (args[0] == "send_it_back_public")
thirdparty = args[0] == "send_it_back_public"
urls.append(self.runtime.handler_url(self, *args, thirdparty=thirdparty))
encoded = json.dumps(urls)
return Fragment(":::" + encoded + ":::")
Expand Down Expand Up @@ -333,7 +333,7 @@ def student_view(self, context):
@temp_scenario(XBlockWithContextTracking, 'context_tracking')
def test_activate_id():
client = Client()
assert XBlockWithContextTracking.registered_contexts == [] # precondition check
assert not XBlockWithContextTracking.registered_contexts # precondition check
client.get("/view/context_tracking/")
assert XBlockWithContextTracking.registered_contexts == [{'activate_block_id': None}]

Expand Down
2 changes: 1 addition & 1 deletion workbench/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def request(self, xblock, handler_name, content, request_method="POST", response
Content of the response (mixed).
"""
# Create a fake request
request = webob.Request(dict())
request = webob.Request({})
request.method = request_method
request.body = content

Expand Down

0 comments on commit fee0ef7

Please sign in to comment.