Skip to content

Commit 43bc7dc

Browse files
authored
Merge pull request #70 from ucfopen/develop
Release Version 6.0.0
2 parents 9081d8e + 83d2cfe commit 43bc7dc

53 files changed

Lines changed: 4542 additions & 2616 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 & 3 deletions
This file was deleted.

.env.template

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Input booleans as either 0 or 1
2+
3+
REQUIREMENTS="requirements.txt"
4+
REDIS_URL="redis://quiz_redis:6379"
5+
6+
DEBUG=0
7+
TESTING=0
8+
9+
# Only needed if you are running the unit test suite
10+
TESTING_API_URL="https://example.edu/"
11+
12+
API_KEY="CHANGEME"
13+
API_URL="https://example.edu/"
14+
15+
PREFERRED_URL_SCHEME="https"
16+
17+
SECRET_KEY="CHANGEME"
18+
19+
MAX_PER_PAGE=100
20+
21+
SQLALCHEMY_DATABASE_URI="mysql://quiz_extensions:password@quiz_db:3306/quiz_extensions"
22+
SQLALCHEMY_TRACK_MODIFICATIONS=0
23+
24+
GOOGLE_ANALYTICS="GA-"
25+
26+
SESSION_COOKIE_SECURE=1
27+
SESSION_COOKIE_SAMESITE="None"

.github/CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
* @keeeeeegan @ssilverm @Thetwam
1+
* @Thetwam
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
name: Publish Images
2+
3+
on:
4+
workflow_run:
5+
workflows: ["Run tests"]
6+
branches: [master]
7+
types:
8+
- completed
9+
10+
env:
11+
REQUIREMENTS: requirements-test.txt
12+
13+
jobs:
14+
build_and_upload_images:
15+
runs-on: ubuntu-latest
16+
if: ${{ github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'push'}}
17+
permissions:
18+
contents: write
19+
packages: write
20+
steps:
21+
- name: Checkout code
22+
uses: actions/checkout@v4
23+
24+
- name: Docker meta for Python
25+
id: meta_python
26+
uses: docker/metadata-action@v5
27+
with:
28+
images: ghcr.io/${{ github.repository_owner }}/quiz-extensions
29+
tags: |
30+
type=semver,pattern={{version}}
31+
type=semver,pattern={{major}}.{{minor}}
32+
type=sha
33+
type=raw,value=dev,enable=${{ startsWith(github.ref, 'refs/tags/v') && (contains(github.ref, '-alpha') || contains(github.ref, '-rc')) }}
34+
35+
- name: Login to GitHub Container Registry
36+
uses: docker/login-action@v3
37+
with:
38+
registry: ghcr.io
39+
username: ${{ github.actor }}
40+
password: ${{ secrets.GITHUB_TOKEN }}
41+
42+
- name: Set up Docker Buildx
43+
uses: docker/setup-buildx-action@v3
44+
45+
- name: Create .env to satisfy build requirements
46+
run: |
47+
if [ ! -f .env ]; then
48+
touch .env
49+
fi
50+
51+
- name: Build Images
52+
run: |
53+
docker compose build --no-cache quiz_extensions
54+
55+
- name: Tag and Push Python Images
56+
run: |
57+
IMAGE_NAME=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep "quiz-extensions-quiz_extensions")
58+
echo "${{ steps.meta_python.outputs.tags }}" | while IFS= read -r tag; do
59+
[ -n "$tag" ] && docker tag "$IMAGE_NAME" "$tag" && docker push "$tag"
60+
done

.github/workflows/run-tests.yml

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,41 +6,52 @@ on:
66
pull_request:
77
branches: [master, develop]
88

9+
env:
10+
REDIS_URL: redis://quiz_redis:6379
11+
SQLALCHEMY_DATABASE_URI: mysql://quiz_extensions:password@quiz_db:3306/quiz_extensions
12+
SECRET_KEY: abc123
13+
TESTING_API_URL: https://test.com/
14+
TESTING_API_KEY: test
15+
API_URL: https://test.com
16+
API_KEY: test
17+
918
jobs:
1019
build:
1120
runs-on: ubuntu-latest
1221
strategy:
1322
matrix:
14-
python-version: [3.7, 3.8, 3.9]
23+
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
1524

1625
steps:
17-
- uses: actions/checkout@v2
26+
- uses: actions/checkout@v6
1827
- name: Set up Python ${{ matrix.python-version }}
19-
uses: actions/setup-python@v2
28+
uses: actions/setup-python@v6
2029
with:
2130
python-version: ${{ matrix.python-version }}
2231
- name: Install XML dependencies
2332
run: sudo apt-get install libxml2-dev libxmlsec1-dev
2433
- name: Install required packages
2534
run: |
2635
python -m pip install --upgrade pip
27-
pip install -r test_requirements.txt
36+
pip install -r requirements-test.txt
2837
pip list
29-
- name: Create config and log files
38+
- name: Create log files
3039
run: |
31-
cp config.py.template config.py
3240
mkdir logs; touch logs/quiz_ext.log
3341
- name: Lint with flake8
3442
run: flake8
3543
- name: Check formatting
3644
uses: psf/black@stable
3745
- name: Check import sorting
3846
uses: jamescurtin/isort-action@master
39-
- name: Lint markdown files
40-
uses: bewuethr/mdl-action@v1
47+
# - name: Lint markdown files
48+
# uses: bewuethr/mdl-action@v1
4149
- name: Run tests
42-
run: coverage run -m unittest discover
50+
run: |
51+
coverage run -m unittest discover -s lti
52+
coverage report
4353
- name: Upload coverage to Codecov
44-
uses: codecov/codecov-action@v1
54+
uses: codecov/codecov-action@v5
4555
with:
56+
token: ${{ secrets.CODECOV_TOKEN }}
4657
fail_ci_if_error: true

.gitignore

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,16 @@
33
.coverage
44
.DS_Store
55
.python-version
6-
config.py
76
/venv*
87
/env*
98
/htmlcov
109
/logs
1110
dump.rdb
11+
*.venv
12+
*.env
13+
lti/nginx.conf
14+
lti/setup.cfg
15+
lti/pyproject.toml
16+
lti/prestart.sh
17+
lti/gunicorn_conf.py
18+
lti/logs

CHANGELOG.md

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,30 @@
22

33
## [Unreleased]
44

5+
## [6.0.0] - 2026-04-10
6+
7+
### General
8+
9+
- Quiz Extensions is now using the LTI 1.3 protocol.
10+
- You will need to redeploy this tool using LTI 1.3 to access the new features. Instructions to do this are in the README.
11+
- *New Quizzes* can now be processed by Quiz Extensions.
12+
- Updated the README to address the deployment method overhaul.
13+
- Tidied interface a bit, including a modal indicating to faculty that New Quiz support is avaliable.
14+
15+
### Bugfixes
16+
17+
- Fixed column breakpoint not working on mobile-sized devices.
18+
19+
### Backstage
20+
21+
- Replaced our Canvas API utility functions with the proper *Canvas API* package. Stale functions have been removed.
22+
- The project has been properly Dockerized now, and upgraded to run Python 3.12.
23+
- Now uses gunicorn as our WSGI server.
24+
- Added a Makefile with commands for various build/deploy/test functions, based off of the UCF Open LTI 1.3 Flask template.
25+
- config.py has been updated to use a .env file, please see *.env.template*.
26+
- Testing suite has been rewritten to use CanvasAPI and LTI 1.3, and has tests for New Quizzes.
27+
- Updated all dependencies to much newer versions.
28+
529
## [5.0.0] - 2021-10-31
630

731
### General
@@ -82,7 +106,8 @@
82106

83107
- Initial release
84108

85-
[Unreleased]: https://github.com/ucfopen/quiz-extensions/compare/v5.0.0...master
109+
[Unreleased]: https://github.com/ucfopen/quiz-extensions/compare/v6.0.0...master
110+
[6.0.0]: https://github.com/ucfopen/quiz-extensions/compare/v5.0.0...v6.0.0
86111
[5.0.0]: https://github.com/ucfopen/quiz-extensions/compare/v4.0.0...v5.0.0
87112
[4.0.0]: https://github.com/ucfopen/quiz-extensions/compare/v3.1.1...v4.0.0
88113
[3.1.1]: https://github.com/ucfopen/quiz-extensions/compare/v3.1.0...v3.1.1

Dockerfile

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
FROM python:3.12
2+
ENV PYTHONUNBUFFERED 1
3+
ARG REQUIREMENTS
4+
5+
WORKDIR /app
6+
COPY requirements.txt /app/
7+
COPY requirements-test.txt /app/
8+
RUN echo $REQUIREMENTS
9+
RUN pip install -r $REQUIREMENTS
10+
COPY ./lti/ /app/
11+
EXPOSE 8000
12+
# To run Gunicorn AND RQ worker:
13+
CMD ["/bin/sh", "-c", "./prestart.sh"]

Makefile

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
include .env
2+
3+
COMPOSE_FILE=docker-compose.yml
4+
DOCKER_COMPOSE=docker compose -f $(COMPOSE_FILE)
5+
6+
BLACK := $(shell tput -Txterm setaf 0)
7+
RED := $(shell tput -Txterm setaf 1)
8+
GREEN := $(shell tput -Txterm setaf 2)
9+
YELLOW := $(shell tput -Txterm setaf 3)
10+
LIGHTPURPLE := $(shell tput -Txterm setaf 4)
11+
PURPLE := $(shell tput -Txterm setaf 5)
12+
BLUE := $(shell tput -Txterm setaf 6)
13+
WHITE := $(shell tput -Txterm setaf 7)
14+
RESET := $(shell tput -Txterm sgr0)
15+
16+
default: build
17+
18+
#==============================================
19+
# Building and cleaning the Docker environment
20+
#==============================================
21+
build: ## Build all Docker images
22+
@echo "Building Quiz Extensions LTI Docker images"
23+
@$(DOCKER_COMPOSE) build
24+
25+
clean: ## Stops and removes existing existing containers and volumes
26+
@echo "${YELLOW}Stopping running containers and purging existing volumes${RESET}"
27+
$(DOCKER_COMPOSE) down -v
28+
@echo "Rebuilding images"
29+
30+
#================================================================================
31+
# Managing the Docker environment (e.g. starting, stopping, deleting containers)
32+
#================================================================================
33+
34+
start: start-daemon ## Start Quiz Extensions LTI (default: daemon mode)
35+
36+
start-attached: ## Start Quiz Extensions LTI in attached mode
37+
@echo "${GREEN}Starting Quiz Extensions LTI in attached mode${RESET}"
38+
$(DOCKER_COMPOSE) up
39+
40+
start-daemon: ## Start Quiz Extensions LTI in daemon mode
41+
@echo "${GREEN}Starting Quiz Extensions LTI in daemon mode${RESET}"
42+
@echo "Run \`make start-attached\` to run in attached mode, or view container logs with \`make logs\`"
43+
$(DOCKER_COMPOSE) up -d
44+
45+
stop: ## Stop all containers
46+
@echo "${YELLOW}Stopping all containers${RESET}"
47+
$(DOCKER_COMPOSE) stop
48+
49+
logs: ## View container logs (optionally specifying a service name, like `quiz_extensions` or `quiz_db`)
50+
$(DOCKER_COMPOSE) logs --tail 10 -f $(filter-out $@,$(MAKECMDGOALS))
51+
52+
#==============================================
53+
# Application management commands
54+
#==============================================
55+
56+
test-all: ## Run all unit tests
57+
$(DOCKER_COMPOSE) run --rm quiz_extensions python -m unittest
58+
59+
lint: ## Run Python linter (flake8)
60+
${DOCKER_COMPOSE} run --rm quiz_extensions flake8 .
61+
62+
format: ## Run Python code formatter (black) and import sorter (isort). Will fix formatting errors.
63+
${DOCKER_COMPOSE} run --rm quiz_extensions sh -c "black . && isort ."
64+
65+
format-check: ## Run Python code formatter (black) and import sorter (isort) in check mode. Will not alter files.
66+
${DOCKER_COMPOSE} run --rm quiz_extensions sh -c "black . --check && isort . --check-only"
67+
68+
lint-format: ## Run Python code formatter (black), import sorter (isort), and linter (flake8). Will fix formatting errors but not linting errors.
69+
${DOCKER_COMPOSE} run --rm quiz_extensions sh -c "black . && isort . && flake8 ."
70+
71+
lint-format-check: ## Run Python code formatter (black) and import sorter (isort) in check mode, and linter (flake8). Will not alter files.
72+
${DOCKER_COMPOSE} run --rm quiz_extensions sh -c "black . --check && isort . --check-only && flake8 ."
73+
74+
migrate-create: ## Create a new DB migration
75+
${DOCKER_COMPOSE} run --rm quiz_extensions flask db migrate
76+
77+
migrate-run: ## Run an existing DB migration
78+
${DOCKER_COMPOSE} run --rm quiz_extensions flask db upgrade
79+
80+
shell: ## Run shell in Flask context
81+
${DOCKER_COMPOSE} run --rm quiz_extensions flask shell
82+
83+
generate-keys: ## Create new public and private keys and assign them to a keyset
84+
${DOCKER_COMPOSE} run --rm quiz_extensions flask generate_keys
85+
86+
register: ## Add a new registration for Quiz Extensions in a platform
87+
${DOCKER_COMPOSE} run --rm quiz_extensions flask register
88+
89+
deploy: ## Add a new deployment for Quiz Extensions to an existing registration
90+
${DOCKER_COMPOSE} run --rm quiz_extensions flask deploy
91+
92+
.PHONY: help
93+
help:
94+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}'

0 commit comments

Comments
 (0)