Skip to content
Snippets Groups Projects
Verified Commit d1ff5fff authored by Tom Teichler's avatar Tom Teichler :beers:
Browse files

Merge branch 'master' of edugit.org:AlekSIS/official/AlekSIS-Core

parents 2ecc8b3f d6833aec
No related branches found
No related tags found
No related merge requests found
Pipeline #4493 passed
Contributor Covenant Code of Conduct
====================================
Our Pledge
----------
We as members, contributors, and leaders pledge to make participation in
our community a harassment-free experience for everyone, regardless of
age, body size, visible or invisible disability, ethnicity, sex
characteristics, gender identity and expression, level of experience,
education, socio-economic status, nationality, personal appearance,
race, religion, or sexual identity and orientation.
We pledge to act and interact in ways that contribute to an open,
welcoming, diverse, inclusive, and healthy community.
Our Standards
-------------
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our
mistakes, and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political
attacks
- Public or private harassment
- Publishing others’ private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
Enforcement Responsibilities
----------------------------
Community leaders are responsible for clarifying and enforcing our
standards of acceptable behavior and will take appropriate and fair
corrective action in response to any behavior that they deem
inappropriate, threatening, offensive, or harmful.
Community leaders have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other
contributions that are not aligned to this Code of Conduct, and will
communicate reasons for moderation decisions when appropriate.
Scope
-----
This Code of Conduct applies within all community spaces, and also
applies when an individual is officially representing the community in
public spaces. Examples of representing our community include using an
official e-mail address, posting via an official social media account,
or acting as an appointed representative at an online or offline event.
Enforcement
-----------
Instances of abusive, harassing, or otherwise unacceptable behavior may
be reported to the community leaders responsible for enforcement at
foss@teckids.org. All complaints will be reviewed and investigated
promptly and fairly.
All community leaders are obligated to respect the privacy and security
of the reporter of any incident.
Enforcement Guidelines
----------------------
Community leaders will follow these Community Impact Guidelines in
determining the consequences for any action they deem in violation of
this Code of Conduct:
1. Correction
~~~~~~~~~~~~~
**Community Impact**: Use of inappropriate language or other behavior
deemed unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders,
providing clarity around the nature of the violation and an explanation
of why the behavior was inappropriate. A public apology may be
requested.
2. Warning
~~~~~~~~~~
**Community Impact**: A violation through a single incident or series of
actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, for a specified period of
time. This includes avoiding interactions in community spaces as well as
external channels like social media. Violating these terms may lead to a
temporary or permanent ban.
3. Temporary Ban
~~~~~~~~~~~~~~~~
**Community Impact**: A serious violation of community standards,
including sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No
public or private interaction with the people involved, including
unsolicited interaction with those enforcing the Code of Conduct, is
allowed during this period. Violating these terms may lead to a
permanent ban.
4. Permanent Ban
~~~~~~~~~~~~~~~~
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of
individuals.
**Consequence**: A permanent ban from any sort of public interaction
within the project community.
Attribution
-----------
This Code of Conduct is adapted from the `Contributor
Covenant <https://www.contributor-covenant.org>`__, version 2.0,
available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by `Mozilla’s code of conduct
enforcement ladder <https://github.com/mozilla/diversity>`__.
For answers to common questions about this code of conduct, see the FAQ
at https://www.contributor-covenant.org/faq. Translations are available
at https://www.contributor-covenant.org/translations.
Development principles and contribution guidelines
==================================================
In order to create a high-quality software product, the AlekSIS developers
have agreed upon fundamental principles governing the code layout, coding
style and repository management for AlekSIS and all official apps.
Coding layout and style
-----------------------
The coding style is defined in `PEP 8`_, with the following differences and
decisions:
- The defaults of the `black`_ code formatter are used
- This implies all string literals usin double-quotes, if it does not lead
to more escaping. As proposed by `black`: "My recommendation here is to
keep using whatever is faster to type and let Black handle the transformation."
- The maximum line length is 100 characters
- Imports are structured in five blocks, each of them sorted as defined in
PEP 8 and the Django style guide:
1. Standard library imports
2. Django imports
3. Third-party imports
4. Imports from AlekSIS core and other apps (absolute imports)
5. Imports from the same AlekSIS app (realtive imports)
Use `isort` to take care of this
For the layout of source trees and style recommendations specific to Django,
the `Django coding style`_ is a good source of information, together with
the `Django Best Practices`_ collection.
To ensure code is styled correctly, before commiting, run::
tox -e reformat
Text documents
~~~~~~~~~~~~~~
If there is no objective reason against it, all text documents accompanying
the source use `reStructuredText`_.
Working with the Git repository
-------------------------------
The Git repository shall be used as a historic documentation of development
and as change management. It is important that the Git commit history
describes what was changed, by whom and why.
Help and information on Git for beginners are available in the `Git guide`_
Feature and issue branches
~~~~~~~~~~~~~~~~~~~~~~~~~~
All features and bug fixes should be developed in their own branch and later
merged into the master branch as a whole. Of course, sometimes, it is
sensible to not do that, e.g. for fixing mere typos and the like.
Within the feature branch, every logical step should be commited separately.
It is neither required nor desired to do micro-commits about every
development step. The commit history should describe the trains of thought
the design and implementation is based on.
If you work on multiple issues at the same time, you have to change between
branches. Never work on unrelated issues in the same branch.
Branches should either contain the number and title of the related issue (as
generated by GitLab), or follow the naming convention type/name, where type
is one of bugfix, feature, or refactor.
All changes on the code should be commited and pushed before stopping work on
in order to prevent data loss. If a logical step is continued later, you
should amend and force-push the commit.
Issue branches should be rebased onto the current master regularly to avoid
merge conflicts.
Commit messages
~~~~~~~~~~~~~~~
Commit messages should be written as described in `How to Write a Git Commit
Message`_.
Commit messages should mention or even close any related issues. For merely
mentioning progress on an issue, use the keyword `advances`; for closing an
issue, use `closes`; for referring to a related issue for informational
purposes, use `cf.`. This should be done in the body of the commit message.
The subject of a commit message can (and should) be prepended with a tag in
square brackets if it relates to a certain part of the repository, e.g. [CI]
when changing CI/CD configuration or support code, [Dev] when changing
something in the development utilities, etc.
Example::
Solve LDAP connection problems
- Add the ldap-with-unicorn-dust dependency
- Configure settings.py to accept the correct groups from LDAP
Closes #10.
Merge Requests
~~~~~~~~~~~~~~
If you think that the work on your feature branch is finished, you have to
create a merge request on EduGit in order to let other developers and the
maintainers take a look at it.
See below on how to submit patches if you cannot use the development
platform.
Manifestos governing development
--------------------------------
The FOSS community has created some manifestos describing several aspects of
software development, to agree upon a baseline for these aspects. The
AlekSIS developers have agreed to adhere to the following manifestos:
- The `Sane software manifesto`_
- The `Accessibility Manifesto`_
- The `User Data Manifesto`_
Not all theses from these manifestos are applicable. For example, most data
about persons in a school information system are dictated by the school and
probably governed by laws defining what and when to store. In that case,
giving the user control over these decisions is not possible. Developers
need to decide what should resonably be followed.
The case on supporting non-free services
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Defined by the `Free Software Definition`_, it is an essential freedom to
be allowed to use free software for any purpose, without limitation. Thus,
interoperability with non-free services shall not be ruled out, and the
AlekSIS project explicitly welcomes implementing support for
interoperability with non-free services.
However, to purposefully foster free software and services, if
interoperability for a certain kind of non-free service is implemented, this
must be done in a generalised manner (i.e. using open protocols and
interfaces). For example, if implementing interoperability with some
cloud-hosted calendar provider can be implemented either through a
proprietary API, or through a standard iCalendar/Webcal interfaces, the
latter is to be preferred. Lacking such support, if a proprietary service
is connected through a proprietary, single-purpose interface, measures shall
be taken to also support alternative free services.
Documentation
-------------
The documentation in the AlekSIS project shall consist of three layers.
Source code comments
~~~~~~~~~~~~~~~~~~~~
The parts of your code that are not self-explaining have to be commented.
Ideally, source code is self-explaining, in the sense that its logical
structure, naming of variables, and the like makes it easy to read and
understand, for a reasonably talented programmer, to follow what it does.
Docstrings
~~~~~~~~~~
All functions, methods, classes and modules that are newly added (or changed
extensively) must contain a docstring for other developers to understand
what it does. Docstrings of public elements will be included in the
developer documentation.
Sphinx documentation
~~~~~~~~~~~~~~~~~~~~
In addition to that you should document the function or the way the app
works in the project documentation (`docs/` directory). Use that especially
for functionality which is shared by your app for other apps (public APIs).
Your Sphinx documentation should contain what the API can and shall be sued
for, and how other apps can benefit from it.
When creating a new app, also include documentation about it targeted at
administrators and users. At least you have to document what new developers
and users have to do in order to get a working instance of the app.
Sphinx documentation for all official apps will be published together.
Contributing to upstream
------------------------
If possible and reasonable, code that can be of use to others in the general
Django ecosystem shall be contributed to any upstream dependency, or a new
generalised upstream dependency be created, under the most permissive
licence possible.
How to contact the team
-----------------------
Development platform
~~~~~~~~~~~~~~~~~~~~
Main development of AlekSIS is done on the `EduGit`_ platform in the
`AlekSIS group`_ and discussions are held on the linked `Mattermost team`_.
All platforms and tools mandated for development are free software and
freely usable. EduGit accepts a variety of sources for login, so
contributors are free to decide where they want to register in order to
participate.
If any contributor cannot use the platforms for whatever reasons, patches and
questions directed at the developers can also be e-mailed to
<aleksis-dev@lists.teckids.org>.
.. _PEP 8: https://pep8.org/
.. _Django coding style: https://docs.djangoproject.com/en/dev/internals/contributing/writing-code/coding-style/
.. _black: https://black.readthedocs.io/en/stable/
.. _Django Best Practices: https://django-best-practices.readthedocs.io/en/latest/index.html
.. _Git guide: https://rogerdudler.github.io/git-guide/
.. _How to Write a Git Commit Message: https://chris.beams.io/posts/git-commit/
.. _Sane software manifesto: https://sane-software.globalcode.info/
.. _Accessibility Manifesto: http://accessibilitymanifesto.com/
.. _User Data Manifesto: https://userdatamanifesto.org/
.. _Free Software Definition: https://www.gnu.org/philosophy/free-sw.en.html
.. _reStructuredText: http://docutils.sourceforge.net/rst.html
.. _EduGit: https://edugit.org/
.. _AlekSIS group: https://edugit.org/AlekSIS/
.. _Mattermost team: https://mattermost.edugit.org/biscuit/
FROM python:3.8-buster AS core
# Configure Python to be nice inside Docker and pip to stfu
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
ENV PIP_DEFAULT_TIMEOUT 100
ENV PIP_DISABLE_PIP_VERSION_CHECK 1
ENV PIP_NO_CACHE_DIR 1
# Configure app settings for build and runtime
ENV ALEKSIS_static__root /usr/share/aleksis/static
ENV ALEKSIS_media__root /var/lib/aleksis/media
ENV ALEKSIS_backup__location /var/lib/aleksis/backups
# Install necessary Debian packages for build and runtime
RUN apt-get -y update && \
apt-get -y install eatmydata && \
eatmydata apt-get -y upgrade && \
eatmydata apt-get install -y --no-install-recommends \
build-essential \
gettext \
libpq5 \
libpq-dev \
libssl-dev \
netcat-openbsd \
yarnpkg
# Install core
WORKDIR /usr/src/app
COPY LICENCE.rst README.rst manage.py poetry.lock pyproject.toml ./
COPY aleksis ./aleksis/
RUN set -e; \
mkdir -p /var/lib/aleksis/media /usr/share/aleksis/static /var/lib/aleksis/backups; \
eatmydata pip install poetry; \
poetry config virtualenvs.create false; \
eatmydata poetry install; \
eatmydata pip install gunicorn django-compressor
# Declare a persistent volume for all data
VOLUME /var/lib/aleksis
# Define entrypoint and gunicorn running on port 8000
EXPOSE 8000
COPY docker/entrypoint.sh /usr/local/bin/
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Install core extras
FROM core AS core-extras
ARG EXTRA_LDAP=1
ARG EXTRA_CELERY=1
WORKDIR /usr/src/app
# LDAP
RUN if [ $EXTRA_LDAP = 1 ] ; then \
eatmydata apt-get install -y --no-install-recommends \
libldap2-dev \
libsasl2-dev \
ldap-utils; \
eatmydata poetry install -E ldap; \
fi;
# Celery
RUN if [ $EXTRA_CELERY = 1 ] ; then \
eatmydata poetry install -E celery; \
fi;
# Install official apps
FROM core-extras AS apps
COPY apps ./apps/
RUN set -e; \
for d in apps/official/*; do \
cd $d; \
rm -rf .git; \
poetry install; \
cd ../../..; \
done
# Build messages and assets
FROM apps as assets
RUN eatmydata python manage.py compilemessages && \
eatmydata python manage.py yarn install && \
eatmydata python manage.py collectstatic --no-input --clear
# Clean up build dependencies
FROM assets AS clean
RUN set -e; \
eatmydata apt-get remove --purge -y \
build-essential \
gettext \
libpq-dev \
libssl-dev \
yarnpkg; \
eatmydata apt-get autoremove --purge -y; \
apt-get clean -y; \
eatmydata pip uninstall -y poetry; \
rm -f /var/lib/apt/lists/*_*; \
rm -rf /root/.cache
build_dist:
stage: build
script:
- if ! [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
poetry version $(poetry version | cut -d" " -f2)+$(date --date=${CI_COMMIT_TIMESTAMP} +%Y%m%d%H%M%S).${CI_COMMIT_SHORT_SHA} ;
fi
- tox -e build
artifacts:
paths:
- dist/
build_docker:
stage: build
image:
name: gcr.io/kaniko-project/executor:debug
entrypoint: [""]
script:
- echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" >/kaniko/.docker/config.json
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
--cache=true
--cleanup
- /kaniko/executor
--context $CI_PROJECT_DIR/docker/nginx
--dockerfile $CI_PROJECT_DIR/docker/nginx/Dockerfile
--destination $CI_REGISTRY_IMAGE/nginx:$CI_COMMIT_REF_NAME
--cache=true
--cleanup
only:
- master
- tags
deploy_demo-master:
stage: deploy
environment:
name: demo/master
url: http://demo-master.aleksis.org
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_KNOWN_HOSTS" >~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- grep -v "build:" docker-compose.yml | ssh root@demo-master.aleksis.org
env ALEKSIS_IMAGE_TAG=${CI_COMMIT_REF_NAME}
docker-compose
-p aleksis-${CI_ENVIRONMENT_SLUG}
-f /dev/stdin
pull
- grep -v "build:" docker-compose.yml | ssh root@demo-master.aleksis.org
env ALEKSIS_IMAGE_TAG=${CI_COMMIT_REF_NAME}
NGINX_HTTP_PORT=80
ALEKSIS_maintenance__debug=true
docker-compose
-p aleksis-${CI_ENVIRONMENT_SLUG}
-f /dev/stdin
up -d
only:
- master
deploy_pypi:
stage: deploy
script:
- if [ $CI_COMMIT_REF_NAME = master ]; then
poetry version $(poetry version | cut -d" " -f2)+$(date --date=${CI_COMMIT_TIMESTAMP} +%Y%m%d%H%M%S).${CI_COMMIT_SHORT_SHA} ;
elif [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
if ! [ "$(poetry version | cut -d" " -f2)" = $CI_COMMIT_REF_NAME ]; then
echo "Package version does not match tag. Aborting build of tag!" >/dev/fd/2 ;
exit 1 ;
fi ;
fi
- if [ $CI_COMMIT_REF_NAME = master ]; then
poetry publish -r gitlab ;
elif [ x$CI_COMMIT_REF_NAME = x$CI_COMMIT_TAG ]; then
poetry publish ;
fi
only:
- master
- tags
image: registry.edugit.org/teckids/team-sysadmin/docker-images/python-pimped:latest
stages:
- test
- build
- deploy
variables:
GIT_SUBMODULE_STRATEGY: recursive
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
FF_NETWORK_PER_BUILD: "true"
POETRY_REPOSITORIES_GITLAB_URL: "$CI_API_V4_URL/projects/461/packages/pypi"
POETRY_HTTP_BASIC_GITLAB_USERNAME: aleksis
POETRY_HTTP_BASIC_GITLAB_PASSWORD: "$GITLAB_PUBLISH_TOKEN"
POETRY_PYPI_TOKEN_PYPI: "$GITLAB_PUBLISH_TOKEN"
cache:
key:
files:
- poetry.lock
- pyproject.toml
paths:
- .cache/pip
- .tox
pages:
stage: deploy
before_script:
- cp -r .tox/screenshots/firefox docs/screenshots
script:
- export LC_ALL=en_GB.utf8
- tox -e docs -- BUILDDIR=../public/docs
artifacts:
paths:
- public/
only:
- master
test:
stage: test
services:
- name: selenium/standalone-firefox
alias: selenium
before_script:
- adduser --disabled-password --gecos "Test User" testuser
- chown -R testuser .
script:
- sudo apt update
- sudo apt install python3-ldap libldap2-dev libssl-dev libsasl2-dev python3.7-dev -y
- sudo -u testuser
env TEST_SELENIUM_HUB=http://selenium:4444/wd/hub
TEST_SELENIUM_BROWSERS=firefox
TEST_HOST=build
tox -e selenium -- --junitxml=.tox/junit.xml
artifacts:
paths:
- .tox/screenshots
reports:
junit: .tox/junit.xml
lint:
stage: test
script:
- tox -e lint,security
version: '3'
services:
db:
image: postgres:12
volumes:
- postgres_data:/var/lib/postgresql/data/
environment:
- POSTGRES_USER=aleksis
- POSTGRES_DB=aleksis
memcached:
image: memcached:latest
app:
build: .
image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
volumes:
- aleksis_data:/var/lib/aleksis/
- aleksis_static:/usr/share/aleksis/static/
environment:
- ALEKSIS_http__allowed_hosts="['*']"
- ALEKSIS_caching__memcached__address=memcached:11211
- ALEKSIS_caching__memcached__enabled=true
- ALEKSIS_database__host=db
- ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
- ALEKSIS_backup__location=/var/lib/aleksis/backups
depends_on:
- db
- memcached
worker:
build: .
image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
volumes:
- aleksis_data:/var/lib/aleksis/
- aleksis_static:/usr/share/aleksis/static/
command: celery_worker
environment:
- ALEKSIS_http__allowed_hosts="['*']"
- ALEKSIS_caching__memcached__address=memcached:11211
- ALEKSIS_caching__memcached__enabled=true
- ALEKSIS_database__host=db
- ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
- ALEKSIS_backup__location=/var/lib/aleksis/backups
depends_on:
- app
scheduler:
build: .
image: registry.edugit.org/aleksis/official/aleksis:${ALEKSIS_IMAGE_TAG:-latest}
volumes:
- aleksis_data:/var/lib/aleksis/
- aleksis_static:/usr/share/aleksis/static/
command: celery_beat
environment:
- ALEKSIS_http__allowed_hosts="['*']"
- ALEKSIS_caching__memcached__address=memcached:11211
- ALEKSIS_caching__memcached__enabled=true
- ALEKSIS_database__host=db
- ALEKSIS_maintenance__debug=${ALEKSIS_maintenance__debug:-false}
depends_on:
- worker
web:
build: ./docker/nginx
image: registry.edugit.org/aleksis/official/aleksis/nginx:${ALEKSIS_IMAGE_TAG:-latest}
volumes:
- aleksis_data:/var/lib/aleksis/
- aleksis_static:/usr/share/aleksis/static/:ro
ports:
- ${NGINX_HTTP_PORT:-8080}:80
depends_on:
- app
volumes:
postgres_data:
aleksis_data:
aleksis_static:
#!/bin/bash
GUNICORN_BIND=${GUNICORN_BIND:-0.0.0.0:8000}
export ALEKSIS_database__host=${ALEKSIS_database__host:-127.0.0.1}
export ALEKSIS_database__port=${ALEKSIS_database__port:-5432}
if [[ -z $ALEKSIS_secret_key ]]; then
if [[ ! -e /var/lib/aleksis/secret_key ]]; then
touch /var/lib/aleksis/secret_key; chmod 600 /var/lib/aleksis/secret_key
LC_ALL=C tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 64 >/var/lib/aleksis/secret_key
fi
ALEKSIS_secret_key=$(</var/lib/aleksis/secret_key)
fi
while ! nc -z $ALEKSIS_database__host $ALEKSIS_database__port; do
sleep 0.1
done
python manage.py compilescss
python manage.py collectstatic --no-input --clear
python manage.py migrate
python manage.py createinitialrevisions
ARG=${$1:-"gunicorn"}
if [ $ARG = "celery_worker" ]; then
exec celery -A aleksis.core worker -l info
elif [ $ARG = "celery_beat" ]; then
exec celery -A aleksis.core beat -l info --scheduler django_celery_beat.schedulers:DatabaseScheduler
else
exec gunicorn aleksis.core.wsgi --bind ${GUNICORN_BIND}
fi
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY nginx.conf /etc/nginx/conf.d/default.conf
RUN mkdir /var/lib/aleksis
upstream aleksis {
server app:8000;
}
server {
listen 80;
location /media/ {
alias /var/lib/aleksis/media/;
}
location /static/ {
alias /usr/share/aleksis/static/;
}
location / {
proxy_pass http://aleksis;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
}
}
#!/usr/bin/env python3
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "aleksis.core.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
......@@ -5,7 +5,7 @@ packages = [
{ include = "aleksis" }
]
readme = "README.rst"
include = ["CHANGELOG.rst", "CODE_OF_CONDUCT.rst", "CONTRIBUTING.rst", "Dockerfile", "LICENCE.rst", "manage.py", "docker/*", "docker/**/*", "docker-compose.yml", "docs/*", "docs/**/*", "tox.ini"]
include = ["CHANGELOG.rst", "LICENCE.rst", "docs/*", "docs/**/*", "aleksis/**/*.mo", "tox.ini"]
description = "AlekSIS (School Information System) — Core"
authors = ["Dominik George <dominik.george@teckids.org>", "Julian Leucker <leuckeju@katharineum.de>", "mirabilos <thorsten.glaser@teckids.org>", "Frank Poetzsch-Heffter <p-h@katharineum.de>", "Tom Teichler <tom.teichler@teckids.org>", "Jonathan Weth <wethjo@katharineum.de>", "Hangzhi Yu <yuha@katharineum.de>"]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment