...
 
Commits (327)
[flake8]
exclude = */migrations/*,*/urls.py
variables:
POSTGRES_DB: thalia
POSTGRES_USER: postgres
POSTGRES_PASSWORD: ""
# https://hub.docker.com/r/thalia/python-thalia/
# https://github.com/thaliawww/python-thalia
# Should get auto-updated with the official 'python' repository
# Installs:
# - pip: coverage, poetry
# - apt: ghostscript
PY37_IMAGE: thalia/python-thalia:3.7
PY38_IMAGE: thalia/python-thalia:3.8
PIP_CACHE_DIR: "${CI_PROJECT_DIR}/pip-cache"
---
stages:
- test
- deploy
codestyle:
stage: test
image: $PY37_IMAGE
before_script:
- poetry install --no-interaction
script:
- poetry run flake8 website
# Check for obsolete translations in .po files (starting with `#~`).
- cd website
- grep --include="*.po" --files-with-matches --recursive "^#~" && exit 1 || echo "No obsolete translations found."
# Check for untranslated strings in .po files
- empty_strings=$(sed '$a\\' **/locale/nl/LC_MESSAGES/django.po | tac | sed '/^$/N;/\nmsgstr ""$/,/^msgid/!d' | tac)
- empty_strings+=$(sed '$a\\' locale/nl/LC_MESSAGES/django.po | tac | sed '/^$/N;/\nmsgstr ""$/,/^msgid/!d' | tac)
- if [[ $empty_strings ]]; then echo $empty_strings && exit 1; else echo "No untranslated strings found."; fi
# Check for fuzzy translations in .po files
- grep --include="*.po" --files-with-matches --recursive "#, fuzzy" && exit 1 || echo "No fuzzy translations found."
.djangotest: &djangotest
stage: test
services:
- postgres:latest
before_script:
- git log -1
- poetry install --no-interaction
script:
- cd website
- poetry run python manage.py check
- poetry run python manage.py templatecheck --project-only
- poetry run python manage.py makemigrations --no-input --check --dry-run
- poetry run python -Wall -mcoverage run manage.py test
- coverage report
python37-django22:
<<: *djangotest
image: $PY37_IMAGE
after_script:
- cd website
- coverage html --directory=covhtml --title="${CI_COMMIT_REF_SLUG} Coverage Report"
artifacts:
paths:
- website/covhtml/
python38-django22:
<<: *djangotest
image: $PY38_IMAGE
allow_failure: true
.sshsetup: &sshsetup
before_script:
- mkdir -p ~/.ssh
- echo "$IVO_KNOWN_HOST" > ~/.ssh/known_hosts
- echo "$COVERAGE_DEPLOY_SSH_KEY" > ~/.ssh/id_coverage
- echo "$DOCS_DEPLOY_SSH_KEY" > ~/.ssh/id_docs
- chmod 0600 ~/.ssh/id_*
- apt-get update
- apt-get install -y openssh-client
coverage deploy:
stage: deploy
image: debian:stretch
dependencies:
- python37-django22
environment:
name: coverage/${CI_COMMIT_REF_NAME}
url: https://coverage.technicie.nl/${CI_COMMIT_REF_SLUG}/
on_stop: coverage remove
<<: *sshsetup
script:
- |
sftp -i ~/.ssh/id_coverage coveragewww@ivo.thalia.nu -b <<EOF
-rm ${CI_COMMIT_REF_SLUG}/*
-rmdir ${CI_COMMIT_REF_SLUG}
put -r website/covhtml ${CI_COMMIT_REF_SLUG}
EOF
coverage remove:
stage: deploy
when: manual
image: debian:stretch
environment:
name: coverage/${CI_COMMIT_REF_NAME}
action: stop
variables:
GIT_STRATEGY: none
<<: *sshsetup
script:
- |
sftp -i ~/.ssh/id_coverage coveragewww@ivo.thalia.nu -b <<EOF
rm ${CI_COMMIT_REF_SLUG}/*
rmdir ${CI_COMMIT_REF_SLUG}
EOF
docs tests:
stage: test
image: $PY37_IMAGE
before_script:
# install django deps
- poetry install --no-interaction --extras "docs"
script:
- echo "Building current docs"
- cd docs
- env -u GITLAB_CI poetry run make doctest
- env -u GITLAB_CI poetry run sphinx-build -W . _build
- echo "Checking if there are changes"
- poetry run ./generate-apidocs.sh
- git diff --exit-code
artifacts:
paths:
- docs/_build
docs deploy:
stage: deploy
image: debian:stretch
dependencies:
- docs tests
environment:
name: docs/${CI_COMMIT_REF_NAME}
url: https://docs.technicie.nl/${CI_COMMIT_REF_SLUG}/
on_stop: docs remove
<<: *sshsetup
script:
- |
sftp -i ~/.ssh/id_docs docswww@ivo.thalia.nu -b <<EOF
-rm ${CI_COMMIT_REF_SLUG}/*/*
-rm ${CI_COMMIT_REF_SLUG}/*
-rmdir ${CI_COMMIT_REF_SLUG}/_images
-rmdir ${CI_COMMIT_REF_SLUG}/_modules
-rmdir ${CI_COMMIT_REF_SLUG}/_sources
-rmdir ${CI_COMMIT_REF_SLUG}/_static
-rmdir ${CI_COMMIT_REF_SLUG}/doctest
-rmdir ${CI_COMMIT_REF_SLUG}/doctrees
-rmdir ${CI_COMMIT_REF_SLUG}
-mkdir ${CI_COMMIT_REF_SLUG}
put -r docs/_build/* ${CI_COMMIT_REF_SLUG}
EOF
docs remove:
stage: deploy
when: manual
image: debian:stretch
environment:
name: docs/${CI_COMMIT_REF_NAME}
action: stop
variables:
GIT_STRATEGY: none
<<: *sshsetup
script:
- |
sftp -i ~/.ssh/id_docs docswww@ivo.thalia.nu -b <<EOF
rm ${CI_COMMIT_REF_SLUG}/*/*
rm ${CI_COMMIT_REF_SLUG}/*
rmdir ${CI_COMMIT_REF_SLUG}/_images
rmdir ${CI_COMMIT_REF_SLUG}/_modules
rmdir ${CI_COMMIT_REF_SLUG}/_sources
rmdir ${CI_COMMIT_REF_SLUG}/_static
rmdir ${CI_COMMIT_REF_SLUG}/doctest
rmdir ${CI_COMMIT_REF_SLUG}/doctrees
rmdir ${CI_COMMIT_REF_SLUG}
EOF
build docker image:
stage: test
services:
- docker:dind
image: thalia/docker-compose
tags:
- docker
except:
- tags
before_script:
- echo $DOCKER_REGISTRY_PASSWORD | docker login --username thaliawww --password-stdin registry.hub.docker.com
script:
- docker-compose config -q
- docker-compose build --build-arg install_dev_requirements=$DEV_REQUIREMENTS --build-arg source_commit=$(git rev-parse HEAD) web
- docker-compose run --rm web test
- docker tag $DOCKER_LATEST $DOCKER_TAG
- docker push $DOCKER_TAG
variables:
DEV_REQUIREMENTS: 1
DOCKER_LATEST: registry.hub.docker.com/thalia/concrexit:latest
DOCKER_TAG: registry.hub.docker.com/thalia/concrexit:$CI_COMMIT_SHA
build production docker image:
extends: build docker image
only:
- tags
except:
- master
after_script:
- docker tag $DOCKER_TAG $DOCKER_TAG_PRODUCTION
- docker tag $DOCKER_TAG $DOCKER_LATEST
- docker push $DOCKER_TAG_PRODUCTION
- docker push $DOCKER_LATEST
variables:
DOCKER_TAG_PRODUCTION: registry.hub.docker.com/thalia/concrexit:$CI_COMMIT_TAG
DEV_REQUIREMENTS: 0
cache:
key: "$CI_JOB_NAME"
paths:
- "${PIP_CACHE_DIR}"
# vim: set sw=2 ts=2 et :
include:
- resources/continuous-integration/config/test.yaml
- resources/continuous-integration/config/build.yaml
- resources/continuous-integration/config/deploy-static-sites.yaml
- resources/continuous-integration/config/deploy-review.yaml
FROM python:3.7
FROM thalia/concrexit-dependencies
MAINTAINER Thalia Technicie <www@thalia.nu>
LABEL description="Contains the Thaliawebsite Django application"
# Arguments
ARG install_dev_requirements=1
ARG source_commit="unknown"
# Try to keep static operation on top to maximise Docker cache utilisation
# Disable output buffering
ENV DJANGO_PRODUCTION 1
ENV PYTHONUNBUFFERED 1
ENV DEBIAN_FRONTEND=noninteractive
ENV SOURCE_COMMIT=${source_commit}
# Set up entrypoint and command
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
# Create /concrexit dir
# Create log dir and log file
# Create app dir
RUN mkdir /concrexit && \
mkdir -p /concrexit/log/ && \
touch /concrexit/log/uwsgi.log && \
chown -R www-data:www-data /concrexit && \
mkdir -p /usr/src/app && \
mkdir -p /usr/src/app/website
# Install dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
postgresql-client \
gettext \
ghostscript && \
rm -rf /var/lib/apt
COPY resources/entrypoint.sh resources/entrypoint_production.sh /usr/local/bin/
RUN pip install --no-cache-dir poetry && \
poetry config settings.virtualenvs.create false
WORKDIR /usr/src/app/website/
# install python requirements
COPY pyproject.toml /usr/src/app/website/
COPY poetry.lock /usr/src/app/website/
RUN if [ "$install_dev_requirements" -eq 1 ]; then \
poetry install --no-interaction; \
else \
echo "This will fail if the dependencies are out of date"; \
poetry install --no-interaction --no-dev; \
fi; \
poetry cache:clear --all --no-interaction pypi
# Create entry points
COPY resources/entrypoint.sh /usr/local/bin/entrypoint.sh
COPY resources/entrypoint_production.sh /usr/local/bin/entrypoint_production.sh
RUN chmod +x /usr/local/bin/entrypoint.sh && \
chmod +x /usr/local/bin/entrypoint_production.sh
RUN mkdir --parents /concrexit/log/ && \
touch /concrexit/log/uwsgi.log && \
chown --recursive www-data:www-data /concrexit/ && \
chmod +x /usr/local/bin/entrypoint.sh /usr/local/bin/entrypoint_production.sh
# copy app source
COPY website /usr/src/app/website/
RUN echo "Don't build releases yourself, let CI do it!"
WORKDIR /usr/src/app/website/
FROM python:3.8
MAINTAINER Thalia Technicie <www@thalia.nu>
LABEL description="Contains the Thaliawebsite dependencies"
ARG install_dev_requirements=1
ENV PATH /root/.poetry/bin:${PATH}
ENV POETRY_VIRTUALENVS_CREATE false
WORKDIR /usr/src/app/
COPY pyproject.toml poetry.lock /usr/src/app/
RUN apt-get update && \
DEBIAN_FRONTEND=noninteractive apt-get install --yes --quiet --no-install-recommends \
postgresql-client \
gettext ghostscript && \
rm --recursive --force /var/lib/apt/lists/* && \
\
curl --silent --show-error --location https://raw.githubusercontent.com/python-poetry/poetry/master/get-poetry.py | python && \
\
if [ "$install_dev_requirements" -eq 1 ]; then \
poetry install --no-interaction --extras "docs"; \
else \
poetry install --no-interaction --no-dev; \
fi; \
poetry cache clear --all --no-interaction pypi
Thalia Website [![coverage report](https://gitlab.science.ru.nl/thalia/concrexit/badges/master/coverage.svg)](https://gitlab.science.ru.nl/thalia/concrexit/commits/master)
Thalia Website [![coverage report](https://gitlab.science.ru.nl/thalia/concrexit/badges/master/coverage.svg)](https://thalia-coverage.s3.amazonaws.com/master/index.html)
==============
New new Thalia website, now with extra Django.
......@@ -28,17 +28,16 @@ Testing and linting
You can use [`pyenv`](https://github.com/pyenv/pyenv) (on Unix systems) to test in different python
environments.
The linter can be run in the `poetry shell` or by running
poetry run flake8 website
All code has to be run through [`black`](https://github.com/psf/black) before being committed. To black the code before committing make run `black` one the base directory of this project.
If you want to integrate `black` with your editor look in the [`black` docs](https://black.readthedocs.io/en/stable/editor_integration.html). On linux you can find the black executable in `~/.cache/poety/virtualenvs/<your env>/bin/black`.
There are a range of tests that can be run:
poetry run python manage.py check
poetry run python manage.py templatecheck --project-only
poetry run python manage.py makemigrations --no-input --check --dry-run
poetry run python -mcoverage run --branch --source '.' manage.py test
coverage report
poetry run python website/manage.py check
poetry run python website/manage.py templatecheck --project-only
poetry run python website/manage.py makemigrations --no-input --check --dry-run
poetry run coverage run website/manage.py test website/
poetry run coverage report
poetry
------
......
......@@ -40,6 +40,14 @@ activemembers.backends module
:undoc-members:
:show-inheritance:
activemembers.emails module
---------------------------
.. automodule:: activemembers.emails
:members:
:undoc-members:
:show-inheritance:
activemembers.forms module
--------------------------
......@@ -48,6 +56,14 @@ activemembers.forms module
:undoc-members:
:show-inheritance:
activemembers.gsuite module
---------------------------
.. automodule:: activemembers.gsuite
:members:
:undoc-members:
:show-inheritance:
activemembers.models module
---------------------------
......@@ -56,6 +72,22 @@ activemembers.models module
:undoc-members:
:show-inheritance:
activemembers.services module
-----------------------------
.. automodule:: activemembers.services
:members:
:undoc-members:
:show-inheritance:
activemembers.signals module
----------------------------
.. automodule:: activemembers.signals
:members:
:undoc-members:
:show-inheritance:
activemembers.sitemaps module
-----------------------------
......
......@@ -20,12 +20,12 @@
import os
import sys
sys.path.insert(0, os.path.abspath('../website'))
sys.path.insert(0, os.path.abspath("../website"))
import django
from django.conf import settings # noqa
from django.conf import settings
from thaliawebsite import settings as thalia_settings # noqa
from thaliawebsite import settings as thalia_settings
# -- Initialise Django ----------------------------------------------------
......@@ -43,23 +43,23 @@ django.setup()
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
'sphinx.ext.graphviz',
'recommonmark',
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.mathjax",
"sphinx.ext.viewcode",
"sphinx.ext.intersphinx",
"sphinx.ext.graphviz",
"recommonmark",
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
templates_path = ["_templates"]
# The master toctree document.
master_doc = 'index'
master_doc = "index"
# General information about the project.
project = 'Concrexit'
project = "Concrexit"
copyright = "2017--2019, Technicie, Studievereniging Thalia"
author = "Technicie, Studievereniging Thalia"
......@@ -68,9 +68,9 @@ author = "Technicie, Studievereniging Thalia"
# built documents.
#
# The short X.Y version.
version = ''
version = ""
# The full version, including alpha/beta/rc tags.
release = ''
release = ""
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
......@@ -82,23 +82,23 @@ language = None
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This patterns also effect to html_static_path and html_extra_path
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = 'sphinx'
pygments_style = "sphinx"
# If true, `todo` and `todoList` produce output, else they produce nothing.
todo_include_todos = False
# default domain:
primary_domain = 'py'
primary_domain = "py"
# -- Options for HTML output ----------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = 'alabaster'
html_theme = "alabaster"
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
......@@ -109,31 +109,28 @@ html_theme = 'alabaster'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
#html_static_path = ['_static']
# html_static_path = ['_static']
# -- Options for HTMLHelp output ------------------------------------------
# Output file base name for HTML help builder.
htmlhelp_basename = 'Concrexitdoc'
htmlhelp_basename = "Concrexitdoc"
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
'maxlistdepth': '10'
"maxlistdepth": "10"
# The paper size ('letterpaper' or 'a4paper').
#
# 'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#
# 'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#
# 'preamble': '',
# Latex figure (float) alignment
#
# 'figure_align': 'htbp',
......@@ -143,8 +140,13 @@ latex_elements = {
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(master_doc, 'Concrexit.tex', 'Concrexit Documentation',
'Thalia Technicie', 'manual'),
(
master_doc,
"Concrexit.tex",
"Concrexit Documentation",
"Thalia Technicie",
"manual",
),
]
......@@ -152,10 +154,7 @@ latex_documents = [
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(master_doc, 'concrexit', 'Concrexit Documentation',
[author], 1)
]
man_pages = [(master_doc, "concrexit", "Concrexit Documentation", [author], 1)]
# -- Options for Texinfo output -------------------------------------------
......@@ -164,35 +163,43 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(master_doc, 'Concrexit', 'Concrexit Documentation',
author, 'Concrexit', "Thalia's website",
'Django Applications'),
(
master_doc,
"Concrexit",
"Concrexit Documentation",
author,
"Concrexit",
"Thalia's website",
"Django Applications",
),
]
# -- Options for autodoc --------------------------------------------------
# Default options for autodoc
autodoc_default_options = {
'members': True,
'undoc-members': True,
"members": True,
"undoc-members": True,
}
# We need to mock the modules for the sphinx build in the docker.
autodoc_mock_imports = ['factory', 'pydenticon', 'faker']
autodoc_mock_imports = ["factory", "pydenticon", "faker"]
# -- Options for doctest --------------------------------------------------
# Disable doctests in normal strings
doctest_test_doctest_blocks = ''
doctest_test_doctest_blocks = ""
# -- intersphinx ---
intersphinx_mapping = {
'python': ('https://docs.python.org/3.7', None),
'django': ('https://docs.djangoproject.com/en/2.2/',
'https://docs.djangoproject.com/en/2.2/_objects/'),
"python": ("https://docs.python.org/3.7", None),
"django": (
"https://docs.djangoproject.com/en/2.2/",
"https://docs.djangoproject.com/en/2.2/_objects/",
),
}
# -- Supress warnings ---
suppress_warnings = [
'image.nonlocal_uri',
"image.nonlocal_uri",
]
......@@ -6,13 +6,6 @@ mailinglists package
:undoc-members:
:show-inheritance:
Subpackages
-----------
.. toctree::
mailinglists.api
Submodules
----------
......@@ -32,6 +25,14 @@ mailinglists.apps module
:undoc-members:
:show-inheritance:
mailinglists.gsuite module
--------------------------
.. automodule:: mailinglists.gsuite
:members:
:undoc-members:
:show-inheritance:
mailinglists.models module
--------------------------
......@@ -48,3 +49,11 @@ mailinglists.services module
:undoc-members:
:show-inheritance:
mailinglists.signals module
---------------------------
.. automodule:: mailinglists.signals
:members:
:undoc-members:
:show-inheritance:
......@@ -19,6 +19,7 @@ website
pizzas
pushnotifications
registrations
singlepages
thabloid
thaliawebsite
utils
......@@ -40,6 +40,14 @@ payments.apps module
:undoc-members:
:show-inheritance:
payments.exceptions module
--------------------------
.. automodule:: payments.exceptions
:members:
:undoc-members:
:show-inheritance:
payments.forms module
---------------------
......
mailinglists.api package
========================
singlepages package
===================
.. automodule:: mailinglists.api
.. automodule:: singlepages
:members:
:undoc-members:
:show-inheritance:
......@@ -9,34 +9,34 @@ mailinglists.api package
Submodules
----------
mailinglists.api.permissions module
-----------------------------------
singlepages.apps module
-----------------------
.. automodule:: mailinglists.api.permissions
.. automodule:: singlepages.apps
:members:
:undoc-members:
:show-inheritance:
mailinglists.api.serializers module
-----------------------------------
singlepages.sitemaps module
---------------------------
.. automodule:: mailinglists.api.serializers
.. automodule:: singlepages.sitemaps
:members:
:undoc-members:
:show-inheritance:
mailinglists.api.urls module
----------------------------
singlepages.urls module
-----------------------
.. automodule:: mailinglists.api.urls
.. automodule:: singlepages.urls
:members:
:undoc-members:
:show-inheritance:
mailinglists.api.viewsets module
--------------------------------
singlepages.views module
------------------------
.. automodule:: mailinglists.api.viewsets
.. automodule:: singlepages.views
:members:
:undoc-members:
:show-inheritance:
......
......@@ -17,3 +17,11 @@ utils.management.commands.createfixtures module
:undoc-members:
:show-inheritance:
utils.management.commands.createreviewuser module
-------------------------------------------------
.. automodule:: utils.management.commands.createreviewuser
:members:
:undoc-members:
:show-inheritance:
......@@ -43,6 +43,14 @@ utils.exception\_filter module
:undoc-members:
:show-inheritance:
utils.google\_api module
------------------------
.. automodule:: utils.google_api
:members:
:undoc-members:
:show-inheritance:
utils.snippets module
---------------------
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -7,43 +7,55 @@ license = "AGPL-3.0-or-later"
[tool.poetry.dependencies]
python = "^3.7"
django-localflavor = "~2.1"
freezegun = "~0.3.11"
bleach = "~3.1"
django-tinymce4-lite = "~1.7"
rcssmin = "~1.0"
djangorestframework = "~3.10"
django-ical = "~1.5"
django-libsass = "~0.7.0"
python-magic = "~0.4.15"
Django = "~2.2"
Pillow = "~6.1"
django_compressor = "~2.2"
psycopg2-binary = "~2.8"
bcrypt = "~3.1"
argon2_cffi = "~19.1"
uWSGI = "~2.0"
django-bootstrap4 = "~1.0.0"
firebase-admin = "~3.0"
sentry-sdk = "~0.12.0"
django-sendfile2 = "~0.4.2"
django-localflavor = { git = "https://github.com/django/django-localflavor.git", rev="d2ce849484640999a2fde7106407f7217a3c95c1" }
freezegun = "0.3.15"
bleach = "3.1.1"
django-tinymce4-lite = "1.7.5"
djangorestframework = "3.11.0"
django-ical = "1.7.0"
django-libsass = "0.8.0"
python-magic = "0.4.15"
Django = "3.0.4"
Pillow = "7.0.0"
django-compressor = "2.4.0"
psycopg2-binary = "2.8.4"
bcrypt = "3.1.7"
argon2_cffi = "19.2.0"
uWSGI = "2.0.18"
django-bootstrap4 = "1.1.1"
firebase-admin = "4.0.0"
sentry-sdk = "0.14.2"
django-sendfile2 = "0.5.1"
# docs requirements
recommonmark = { version = "~0.6.0", optional = true }
sphinx = { version = "~2.2", optional = true }
recommonmark = { version = "0.6.0", optional = true }
sphinx = { version = "2.4.4", optional = true }
google-api-python-client = "1.7.12"
[tool.poetry.extras]
docs = ["recommonmark", "sphinx"]
[tool.poetry.dev-dependencies]
django-template-check = "~0.3.1"
factory_boy = "~2.12"
flake8 = "~3.7"
pydenticon = "~0.3.1"
pylint = "~2.4"
pylint-django = "~2.0"
Faker = "~2.0"
coverage = "~4.5"
django-template-check = "0.3.1"
factory_boy = "2.12"
pydenticon = "0.3.1"
Faker = "4.0"
coverage = {extras = ["toml"], version = "^5.0.3"}
black = "19.10b0"
[tool.coverage.run]
branch = true
source = ["website"]
omit = ["website/manage.py", "website/thaliawebsite/wsgi.py", "website/thaliawebsite/settings/*", "website/*/migrations/*", "website/*/test*"]
[tool.coverage.report]
precision = 2
skip_covered = true
show_missing = true
fail_under = 65.0
[tool.black]
exclude = '(/(\.eggs|\.git|\.tox)/|migrations)'
[build-system]
requires = ["poetry>=0.12"]
......
.build-docker-image-setup:
stage: test
tags:
- docker
image: docker
services:
- docker:dind
before_script:
- echo "$DOCKER_REGISTRY_PASSWORD" | docker login --username "thaliawww" --password-stdin "registry.hub.docker.com"
variables:
DOCKER_LATEST: registry.hub.docker.com/thalia/concrexit:latest
DOCKER_TAG: registry.hub.docker.com/thalia/concrexit:${CI_COMMIT_SHA}
DOCKER_DEPENDENCIES_LATEST: registry.hub.docker.com/thalia/concrexit-dependencies:latest
DOCKER_TAG_PRODUCTION: registry.hub.docker.com/thalia/concrexit:${CI_COMMIT_TAG}
schedule:build-docker-image-dependencies:
extends: .build-docker-image-setup
only:
- schedules
script:
- docker build --file "Dockerfile.dependencies" --quiet --build-arg "install_dev_requirements=1" --tag "${DOCKER_DEPENDENCIES_LATEST}" .
- docker push "${DOCKER_DEPENDENCIES_LATEST}"
build-docker-image:
extends: .build-docker-image-setup
except:
- /v[\d\.]+/
- schedules
script:
- docker build --quiet --build-arg "source_commit=${CI_COMMIT_SHA}" --tag "${DOCKER_LATEST}" .
- docker tag "${DOCKER_LATEST}" "${DOCKER_TAG}"
- docker push "${DOCKER_TAG}"
build-docker-image-production:
extends: .build-docker-image-setup
only:
- /v[\d\.]+/
script:
- docker build --file "Dockerfile.dependencies" --quiet --build-arg "install_dev_requirements=0" --tag "${DOCKER_DEPENDENCIES_LATEST}" .
- docker build --quiet --build-arg "source_commit=${CI_COMMIT_SHA}" --tag "${DOCKER_LATEST}" .
- docker tag "${DOCKER_LATEST}" "${DOCKER_TAG_PRODUCTION}"
- docker push "${DOCKER_TAG_PRODUCTION}"
- docker push "${DOCKER_LATEST}"
---
.review-setup:
when: manual
stage: deploy
except:
- schedules
image: python:latest
before_script:
- DEBIAN_FRONTEND=noninteractive apt-get --yes --quiet update
- DEBIAN_FRONTEND=noninteractive apt-get --yes --quiet install jq
- pip install awscli
variables:
AWS_DEFAULT_REGION: eu-west-1
review-create:
extends: .review-setup
environment:
name: review/${CI_COMMIT_REF_NAME}
url: https://${CI_COMMIT_REF_SLUG}.public.review.technicie.nl/
on_stop: review-remove
script:
- username=$(head /dev/urandom | tr -dc 'a-z' | head -c 10)
- password=$(head /dev/urandom | tr -dc 'a-zA-Z' | head -c 32)
- >-
sed --in-place
--expression "s/@version@/$CI_COMMIT_SHA/g"
--expression "s/@username@/$username/g"
--expression "s/@password@/$password/g"
resources/continuous-integration/review/ec2-bootstrap.sh
- resources/continuous-integration/review/review-host-create.sh
- echo -e "The deployment is done. Please wait for the website to come up. You can login on https://${CI_COMMIT_REF_SLUG}.public.review.technicie.nl/ with:\nUsername:$username\nPassword:$password"
review-remove:
extends: .review-setup
environment:
name: review/${CI_COMMIT_REF_NAME}
action: stop
script:
- resources/continuous-integration/review/review-host-remove.sh
---
coverage-deploy:
stage: deploy
except:
- schedules
dependencies:
- django-tests
environment:
name: coverage/${CI_COMMIT_REF_NAME}
url: https://s3-eu-west-1.amazonaws.com/thalia-coverage/${CI_COMMIT_REF_SLUG}/index.html
image: python:latest
before_script:
- pip install awscli
script:
- aws s3 sync --only-show-errors "covhtml" "s3://thalia-coverage/${CI_COMMIT_REF_SLUG}/"
docs-deploy:
stage: deploy
except:
- schedules
dependencies:
- docs-tests
environment:
name: documentation/${CI_COMMIT_REF_NAME}
url: https://s3-eu-west-1.amazonaws.com/thalia-documentation/${CI_COMMIT_REF_SLUG}/index.html
image: python:latest
before_script:
- pip install awscli
script:
- aws s3 sync --only-show-errors "docs/_build" "s3://thalia-documentation/${CI_COMMIT_REF_SLUG}/"
---
codestyle:
stage: test
except:
- schedules
image: thalia/concrexit-dependencies
before_script:
- poetry install --no-interaction
script:
- black --quiet --check website
# Check for obsolete translations in .po files (starting with `#~`).
- grep --include="*.po" --files-with-matches --recursive "^#~" website && exit 1 || echo "No obsolete translations found."
# Check for untranslated strings in .po files
- empty_strings=$(sed '$a\\' website/**/locale/nl/LC_MESSAGES/django.po | tac | sed '/^$/N;/\nmsgstr ""$/,/^msgid/!d' | tac)
- empty_strings+=$(sed '$a\\' website/locale/nl/LC_MESSAGES/django.po | tac | sed '/^$/N;/\nmsgstr ""$/,/^msgid/!d' | tac)
- if [[ $empty_strings ]]; then echo $empty_strings && exit 1; else echo "No untranslated strings found."; fi
# Check for fuzzy translations in .po files
- grep --include="*.po" --files-with-matches --recursive "#, fuzzy" website && exit 1 || echo "No fuzzy translations found."
django-tests:
stage: test
except:
- schedules
image: thalia/concrexit-dependencies
services:
- postgres:latest
before_script:
- git log -1
- poetry install --no-interaction
script:
- poetry run python website/manage.py check
- poetry run python website/manage.py templatecheck --project-only
- poetry run python website/manage.py makemigrations --no-input --check --dry-run
- poetry run coverage run website/manage.py test website/
- coverage report --fail-under=100 --omit "website/registrations/urls.py" website/registrations/**.py
- coverage report --fail-under=100 --omit "website/payments/urls.py" website/payments/**.py
- coverage report
after_script:
- coverage html --directory=covhtml --title="${CI_COMMIT_REF_SLUG} Coverage Report"
variables:
POSTGRES_DB: thalia
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
artifacts:
paths:
- covhtml
docs-tests:
stage: test
except:
- schedules
image: thalia/concrexit-dependencies
before_script:
- poetry install --no-interaction --extras "docs"
script:
- echo "Building current docs"
- cd docs
- env -u GITLAB_CI poetry run make doctest
- env -u GITLAB_CI poetry run sphinx-build -W . _build
- echo "Checking if there are changes"
- poetry run ./generate-apidocs.sh
- git diff --exit-code
artifacts:
paths:
- docs/_build
#!/usr/bin/env bash
# From https://docs.docker.com/install/linux/docker-ce/ubuntu/
apt-get update
apt-get install -y apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add -
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
apt-get update
apt-get -y install docker-ce docker-ce-cli containerd.io
docker volume create concrexit_data
docker run --name concrexit_migrate \
--rm \
--mount source=concrexit_data,target=/usr/src/app/website/ \
thalia/concrexit:@version@ migrate
docker run --name concrexit_superuser \
--rm \
--mount source=concrexit_data,target=/usr/src/app/website/ \
thalia/concrexit:@version@ createreviewuser \
--username @username@ --password @password@
docker run --name concrexit_fixtures \
--rm \
--mount source=concrexit_data,target=/usr/src/app/website/ \
thalia/concrexit:@version@ createfixtures -a
docker run --name concrexit_web \
--detach \
--publish 0.0.0.0:80:80 \
--mount source=concrexit_data,target=/usr/src/app/website/ \
thalia/concrexit:@version@ runserver 0.0.0.0:80
echo "shutdown now" | at now +2 days
#!/usr/bin/env bash
set -o errexit -o verbose
if [ -z "${GITLAB_CI}" ]; then
echo "Not running in Gitlab CI"
exit 1;
fi
mapfile -t running_instance_ids < <(
aws ec2 describe-instances \
--filters "Name=tag:Name,Values=concrexit-review-${CI_COMMIT_REF_SLUG}" \
"Name=instance-state-name,Values=running,shutting-down,stopping,stopped" \
--query "Reservations[].Instances[].[InstanceId]" \
--output "text"
)
if [ "${#running_instance_ids[@]}" -gt 0 ]; then
aws ec2 terminate-instances --instance-ids "${running_instance_ids[@]}"
fi
new_instance_id=$(
aws ec2 run-instances \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=concrexit-review-${CI_COMMIT_REF_SLUG}}]" \
--launch-template "LaunchTemplateId=lt-03762fc23450c2471,Version=5" \
--user-data file://resources/continuous-integration/review/ec2-bootstrap.sh |
jq --raw-output ".Instances[0].InstanceId"
)
aws ec2 wait instance-running --instance-ids "${new_instance_id}"
private_ipv4_address=$(aws ec2 describe-instances --instance-ids "${new_instance_id}" | jq --raw-output '.Reservations[0].Instances[0].PrivateIpAddress')
temporary_record_change_file=$(mktemp --suffix ".json")
cat > "${temporary_record_change_file}" <<EOF
{
"Comment": "Add or update private review host record",
"Changes": [
{
"Action": "UPSERT",
"ResourceRecordSet": {
"Name": "${CI_COMMIT_REF_SLUG}.private.review.technicie.nl",
"Type": "A",
"TTL": 10,
"ResourceRecords": [{"Value": "${private_ipv4_address}"}]
}
}
]
}
EOF
route53_record_change_id=$(