diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..d0fde72 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,9 @@ +version: 2 +updates: + # Adding new check for github-actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + reviewers: + - "openedx/arbi-bom" diff --git a/.github/workflows/add-depr-ticket-to-depr-board.yml b/.github/workflows/add-depr-ticket-to-depr-board.yml new file mode 100644 index 0000000..250e394 --- /dev/null +++ b/.github/workflows/add-depr-ticket-to-depr-board.yml @@ -0,0 +1,19 @@ +# Run the workflow that adds new tickets that are either: +# - labelled "DEPR" +# - title starts with "[DEPR]" +# - body starts with "Proposal Date" (this is the first template field) +# to the org-wide DEPR project board + +name: Add newly created DEPR issues to the DEPR project board + +on: + issues: + types: [opened] + +jobs: + routeissue: + uses: openedx/.github/.github/workflows/add-depr-ticket-to-depr-board.yml@master + secrets: + GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }} + GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }} + SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }} diff --git a/.github/workflows/add-remove-label-on-comment.yml b/.github/workflows/add-remove-label-on-comment.yml new file mode 100644 index 0000000..0f369db --- /dev/null +++ b/.github/workflows/add-remove-label-on-comment.yml @@ -0,0 +1,20 @@ +# This workflow runs when a comment is made on the ticket +# If the comment starts with "label: " it tries to apply +# the label indicated in rest of comment. +# If the comment starts with "remove label: ", it tries +# to remove the indicated label. +# Note: Labels are allowed to have spaces and this script does +# not parse spaces (as often a space is legitimate), so the command +# "label: really long lots of words label" will apply the +# label "really long lots of words label" + +name: Allows for the adding and removing of labels via comment + +on: + issue_comment: + types: [created] + +jobs: + add_remove_labels: + uses: openedx/.github/.github/workflows/add-remove-label-on-comment.yml@master + diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 0000000..fec11d6 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,10 @@ +# Run commitlint on the commit messages in a pull request. + +name: Lint Commit Messages + +on: + - pull_request + +jobs: + commitlint: + uses: openedx/.github/.github/workflows/commitlint.yml@master diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml new file mode 100644 index 0000000..3aab45a --- /dev/null +++ b/.github/workflows/pypi-publish.yml @@ -0,0 +1,30 @@ +name: Publish package to PyPI + +on: + push: + tags: + - '*' + +jobs: + push: + runs-on: ubuntu-20.04 + + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: setup python + uses: actions/setup-python@v3 + with: + python-version: 3.8 + + - name: Install pip + run: pip install -r requirements/pip.txt + + - name: Build package + run: python setup.py sdist bdist_wheel + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@master + with: + user: __token__ + password: ${{ secrets.PYPI_UPLOAD_TOKEN }} diff --git a/.github/workflows/self-assign-issue.yml b/.github/workflows/self-assign-issue.yml new file mode 100644 index 0000000..37522fd --- /dev/null +++ b/.github/workflows/self-assign-issue.yml @@ -0,0 +1,12 @@ +# This workflow runs when a comment is made on the ticket +# If the comment starts with "assign me" it assigns the author to the +# ticket (case insensitive) + +name: Assign comment author to ticket if they say "assign me" +on: + issue_comment: + types: [created] + +jobs: + self_assign_by_comment: + uses: openedx/.github/.github/workflows/self-assign-issue.yml@master diff --git a/.github/workflows/upgrade-python-requirements.yml b/.github/workflows/upgrade-python-requirements.yml new file mode 100644 index 0000000..71562a1 --- /dev/null +++ b/.github/workflows/upgrade-python-requirements.yml @@ -0,0 +1,27 @@ +name: Upgrade Python Requirements + +on: + schedule: + - cron: "0 0 * * 1" + workflow_dispatch: + inputs: + branch: + description: "Target branch against which to create requirements PR" + required: true + default: 'master' + +jobs: + call-upgrade-python-requirements-workflow: + uses: openedx/.github/.github/workflows/upgrade-python-requirements.yml@master + with: + branch: ${{ github.event.inputs.branch || 'master' }} + # optional parameters below; fill in if you'd like github or email notifications + # user_reviewers: "" + team_reviewers: "arbi-bom" + email_address: "arbi-bom@edx.org" + send_success_notification: false + secrets: + requirements_bot_github_token: ${{ secrets.REQUIREMENTS_BOT_GITHUB_TOKEN }} + requirements_bot_github_email: ${{ secrets.REQUIREMENTS_BOT_GITHUB_EMAIL }} + edx_smtp_username: ${{ secrets.EDX_SMTP_USERNAME }} + edx_smtp_password: ${{ secrets.EDX_SMTP_PASSWORD }} diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6e7e774 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +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 "$(@)" + +upgrade: export CUSTOM_COMPILE_COMMAND=make upgrade +upgrade: $(COMMON_CONSTRAINTS_TXT) ## update the requirements/*.txt files with the latest packages satisfying requirements/*.in + pip install -q -r requirements/pip_tools.txt + pip-compile --allow-unsafe --rebuild --upgrade -o requirements/pip.txt requirements/pip.in + pip-compile --upgrade -o requirements/pip_tools.txt requirements/pip_tools.in + pip install -q -r requirements/pip.txt + pip install -q -r requirements/pip_tools.txt + pip-compile --upgrade -o requirements/base.txt requirements/base.in diff --git a/concept/concept.py b/concept/concept.py index d86d72b..e463495 100644 --- a/concept/concept.py +++ b/concept/concept.py @@ -2,14 +2,16 @@ can integrate with the LMS more easily than with Studio, so it's in many ways an easier environment where to do this.""" -import pkg_resources -import json, requests +import json +import pkg_resources from xblock.core import XBlock -from xblock.fields import Scope, Integer, String +from xblock.fields import Integer, Scope, String from xblock.fragment import Fragment +import requests + class ConceptXBlock(XBlock): """ diff --git a/concept/static/js/oa_edit.js b/concept/static/js/oa_edit.js index 0ab365b..a10ac82 100644 Binary files a/concept/static/js/oa_edit.js and b/concept/static/js/oa_edit.js differ diff --git a/concept/static/js/oa_server.js b/concept/static/js/oa_server.js index 4d63920..eb572b1 100644 Binary files a/concept/static/js/oa_server.js and b/concept/static/js/oa_server.js differ diff --git a/openedx.yaml b/openedx.yaml new file mode 100644 index 0000000..f99cd3c --- /dev/null +++ b/openedx.yaml @@ -0,0 +1,10 @@ +# This file describes this Open edX repo, as described in OEP-2: +# https://open-edx-proposals.readthedocs.io/en/latest/oep-0002-bp-repo-metadata.html#specification + +oeps: + oep-2: True + oep-7: True + oep-18: True + +tags: + - xblock diff --git a/requirements/base.in b/requirements/base.in new file mode 100644 index 0000000..45fea65 --- /dev/null +++ b/requirements/base.in @@ -0,0 +1,4 @@ +# Core requirements for using this package +-c constraints.txt + +XBlock diff --git a/requirements/base.txt b/requirements/base.txt new file mode 100644 index 0000000..f254618 --- /dev/null +++ b/requirements/base.txt @@ -0,0 +1,33 @@ +# +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: +# +# make upgrade +# +appdirs==1.4.4 + # via fs +fs==2.4.16 + # via xblock +lxml==4.9.3 + # via xblock +markupsafe==2.1.3 + # via xblock +python-dateutil==2.8.2 + # via xblock +pytz==2023.3.post1 + # via xblock +pyyaml==6.0.1 + # via xblock +six==1.16.0 + # via + # fs + # python-dateutil +web-fragments==2.1.0 + # via xblock +webob==1.8.7 + # via xblock +xblock==1.7.0 + # via -r requirements/base.in + +# The following packages are considered to be unsafe in a requirements file: +# setuptools diff --git a/requirements/common_constraints.txt b/requirements/common_constraints.txt new file mode 100644 index 0000000..afe6aa8 --- /dev/null +++ b/requirements/common_constraints.txt @@ -0,0 +1,27 @@ +# A central location for most common version constraints +# (across edx repos) for pip-installation. +# +# Similar to other constraint files this file doesn't install any packages. +# It specifies version constraints that will be applied if a package is needed. +# When pinning something here, please provide an explanation of why it is a good +# idea to pin this package across all edx repos, Ideally, link to other information +# that will help people in the future to remove the pin when possible. +# Writing an issue against the offending project and linking to it here is good. +# +# Note: Changes to this file will automatically be used by other repos, referencing +# this file from Github directly. It does not require packaging in edx-lint. + + +# using LTS django version +Django<4.0 + +# elasticsearch>=7.14.0 includes breaking changes in it which caused issues in discovery upgrade process. +# elastic search changelog: https://www.elastic.co/guide/en/enterprise-search/master/release-notes-7.14.0.html +elasticsearch<7.14.0 + +# django-simple-history>3.0.0 adds indexing and causes a lot of migrations to be affected +django-simple-history==3.0.0 + +# tox>4.0.0 isn't yet compatible with many tox plugins, causing CI failures in almost all repos. +# Details can be found in this discussion: https://github.com/tox-dev/tox/discussions/1810 +tox<4.0.0 diff --git a/requirements/constraints.txt b/requirements/constraints.txt new file mode 100644 index 0000000..a51cb08 --- /dev/null +++ b/requirements/constraints.txt @@ -0,0 +1,12 @@ +# Version constraints for pip-installation. +# +# This file doesn't install any packages. It specifies version constraints +# that will be applied if a package is needed. +# +# When pinning something here, please provide an explanation of why. Ideally, +# link to other information that will help people in the future to remove the +# pin when possible. Writing an issue against the offending project and +# linking to it here is good. + +# Common constraints for edx repos +-c common_constraints.txt diff --git a/requirements/pip.in b/requirements/pip.in new file mode 100644 index 0000000..715478c --- /dev/null +++ b/requirements/pip.in @@ -0,0 +1,7 @@ +-c constraints.txt +# Core dependencies for installing other packages + +pip +setuptools +wheel + diff --git a/requirements/pip.txt b/requirements/pip.txt new file mode 100644 index 0000000..3e7d8f4 --- /dev/null +++ b/requirements/pip.txt @@ -0,0 +1,14 @@ +# +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: +# +# make upgrade +# +wheel==0.41.2 + # via -r requirements/pip.in + +# The following packages are considered to be unsafe in a requirements file: +pip==23.2.1 + # via -r requirements/pip.in +setuptools==68.2.2 + # via -r requirements/pip.in diff --git a/requirements/pip_tools.in b/requirements/pip_tools.in new file mode 100644 index 0000000..caf45a9 --- /dev/null +++ b/requirements/pip_tools.in @@ -0,0 +1,4 @@ + # Dependencies to run compile tools +-c constraints.txt + +pip-tools # Contains pip-compile, used to generate pip requirements files diff --git a/requirements/pip_tools.txt b/requirements/pip_tools.txt new file mode 100644 index 0000000..05d0731 --- /dev/null +++ b/requirements/pip_tools.txt @@ -0,0 +1,31 @@ +# +# This file is autogenerated by pip-compile with Python 3.8 +# by the following command: +# +# make upgrade +# +build==1.0.3 + # via pip-tools +click==8.1.7 + # via pip-tools +importlib-metadata==6.8.0 + # via build +packaging==23.1 + # via build +pip-tools==7.3.0 + # via -r requirements/pip_tools.in +pyproject-hooks==1.0.0 + # via build +tomli==2.0.1 + # via + # build + # pip-tools + # pyproject-hooks +wheel==0.41.2 + # via pip-tools +zipp==3.17.0 + # via importlib-metadata + +# The following packages are considered to be unsafe in a requirements file: +# pip +# setuptools diff --git a/setup.py b/setup.py index 44313bf..9f6236f 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,9 @@ """Setup for concept XBlock.""" + import os +import re + from setuptools import setup @@ -14,16 +17,77 @@ def package_data(pkg, root): return {pkg: data} +# UPDATED VIA SEMGREP - if you need to remove/modify this method remove this line and add a comment specifying why. +def load_requirements(*requirements_paths): + """ + Load all requirements from the specified requirements files. + + Requirements will include any constraints from files specified + with -c in the requirements files. + Returns a list of requirement strings. + """ + requirements = {} + constraint_files = set() + + # groups "my-package-name<=x.y.z,..." into ("my-package-name", "<=x.y.z,...") + requirement_line_regex = re.compile(r"([a-zA-Z0-9-_.]+)([<>=][^#\s]+)?") + + def add_version_constraint_or_raise(current_line, current_requirements, add_if_not_present): + regex_match = requirement_line_regex.match(current_line) + if regex_match: + package = regex_match.group(1) + version_constraints = regex_match.group(2) + existing_version_constraints = current_requirements.get(package, None) + # it's fine to add constraints to an unconstrained package, but raise an error if there are already + # constraints in place + if existing_version_constraints and existing_version_constraints != version_constraints: + raise BaseException(f'Multiple constraint definitions found for {package}:' + f' {existing_version_constraints} and {version_constraints}.' + f'Combine constraints into one location with {package}' + f'{existing_version_constraints},{version_constraints}.') + if add_if_not_present or package in current_requirements: + current_requirements[package] = version_constraints + + # process .in files and store the path to any constraint files that are pulled in + for path in requirements_paths: + with open(path) as reqs: + for line in reqs: + if is_requirement(line): + add_version_constraint_or_raise(line, requirements, True) + if line and line.startswith('-c') and not line.startswith('-c http'): + constraint_files.add(os.path.dirname(path) + '/' + line.split('#')[0].replace('-c', '').strip()) + + # process constraint files and add any new constraints found to existing requirements + for constraint_file in constraint_files: + with open(constraint_file) as reader: + for line in reader: + if is_requirement(line): + add_version_constraint_or_raise(line, requirements, False) + + # process back into list of pkg><=constraints strings + return [f'{pkg}{version or ""}' for (pkg, version) in sorted(requirements.items())] + + +# UPDATED VIA SEMGREP - if you need to remove/modify this method remove this line and add a comment specifying why +def is_requirement(line): + """ + Return True if the requirement line is a package requirement. + + Returns: + bool: True if the line is not blank, a comment, + a URL, or an included file + """ + return line and line.strip() and not line.startswith(('-r', '#', '-e', 'git+', '-c')) + + setup( name='concept-xblock', - version='0.1', + version='0.2.0', description='concept XBlock', # TODO: write a better description. packages=[ 'concept', ], - install_requires=[ - 'XBlock', - ], + install_requires=load_requirements('requirements/base.in'), entry_points={ 'xblock.v1': [ 'concept = concept:ConceptXBlock',