Feat/scroll header #209
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: Continuous Integration and Continuous Deployment to DigitalOcean Droplet | |
on: | |
push: | |
branches: [ "main" ] | |
pull_request: | |
permissions: | |
contents: read | |
jobs: | |
Build: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Setup Python version | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
- uses: actions/cache@v3 | |
with: | |
path: ~/.cache/pip | |
key: ${{ runner.os }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} | |
restore-keys: ${{ runner.os }}-pip- | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi | |
Tests: | |
needs: Build | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Setup Python version | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
- name: Install PostgreSQL | |
run: | | |
sudo apt-get update | |
sudo apt-get install postgresql postgresql-contrib -y | |
sudo service postgresql start | |
sudo -u postgres psql -c "CREATE DATABASE ${{ secrets.DB_NAME }};" | |
sudo -u postgres psql -c "ALTER USER ${{ secrets.DB_USER }} WITH PASSWORD '${{ secrets.DB_PASSWORD }}';" | |
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${{ secrets.DB_NAME }} TO ${{ secrets.DB_USER }};" | |
- uses: actions/cache@v3 | |
with: | |
path: ~/.cache/pip | |
key: ${{ runner.os }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} | |
restore-keys: ${{ runner.os }}-pip- | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi | |
- name: Test with Pytest | |
run: | | |
python manage.py collectstatic --no-input | |
coverage run --source='.' manage.py test | |
coverage xml | |
env: | |
CI: true | |
DB_HOST: ${{ secrets.DB_HOST }} | |
DB_PORT: ${{ secrets.DB_PORT }} | |
DB_NAME: ${{ secrets.DB_NAME }} | |
DB_USER: ${{ secrets.DB_USER }} | |
DB_PASSWORD: ${{ secrets.DB_PASSWORD }} | |
SECRET_KEY: ${{ secrets.SECRET_KEY }} | |
ALLOWED_HOSTS: ${{ secrets.ALLOWED_HOSTS }} | |
DEBUG: ${{ secrets.DEBUG }} | |
EMAIL_HOST_USER: ${{ secrets.EMAIL_HOST_USER }} | |
EMAIL_HOST_PASSWORD: ${{ secrets.EMAIL_HOST_PASSWORD }} | |
GOOGLE_CLIENT_ID: ${{ secrets.GOOGLE_CLIENT_ID }} | |
GOOGLE_SECRET: ${{ secrets.GOOGLE_SECRET }} | |
CSRF_TRUSTED_ORIGINS: ${{ secrets.CSRF_TRUSTED_ORIGINS }} | |
USE_X_FORWARDED_HOST: ${{ secrets.USE_X_FORWARDED_HOST }} | |
- name: Upload coverage report | |
uses: actions/upload-artifact@v2 | |
with: | |
name: pytest-coverage | |
path: | | |
./coverage.xml | |
- name: Check coverage | |
run: | | |
export coverage=$(grep -oP 'line-rate="\K[^"]+' coverage.xml | head -1 | awk '{print $1 * 100}') | |
echo "Code coverage: $coverage%" | |
if (( $(echo "$coverage < 50" | bc -l) )); then | |
echo "Code coverage is less than 60%: $coverage%" | |
exit 1 | |
fi | |
Linters: | |
needs: Build | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v3 | |
- name: Setup Python version | |
uses: actions/setup-python@v4 | |
with: | |
python-version: "3.11" | |
- uses: actions/cache@v3 | |
with: | |
path: ~/.cache/pip | |
key: ${{ runner.os }}-${{ hashFiles('requirements.txt') }}-${{ hashFiles('requirements-dev.txt') }} | |
restore-keys: ${{ runner.os }}-pip- | |
- name: Install dependencies | |
run: | | |
python -m pip install --upgrade pip | |
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi | |
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi | |
- name: Check code formatting with Flake8 | |
run: | | |
# stop the build if there are Python syntax errors or undefined names | |
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics | |
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide | |
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics | |
- name: Check code formatting with Black | |
run: | | |
black --check --verbose . | |
Deploy: | |
needs: [Build, Tests, Linters] | |
if: github.event_name == 'push' && github.ref == 'refs/heads/main' | |
runs-on: ubuntu-latest | |
steps: | |
- name: Deploy to digital ocean | |
uses: appleboy/[email protected] | |
with: | |
host: ${{secrets.SSH_HOST}} | |
key: ${{secrets.SSH_KEY}} | |
username: ${{ secrets.SSH_USERNAME }} | |
password: ${{ secrets.DROPLET_PASSWORD }} | |
script: | | |
directory="/var/www/vr-club" | |
if [ -d "$directory" ]; then | |
cd /var/www/ | |
cd vr-club | |
source venv/bin/activate | |
export DB_HOST='${{ secrets.DB_HOST }}' | |
export DB_PORT='${{ secrets.DB_PORT }}' | |
export DB_NAME='${{ secrets.DB_NAME }}' | |
export DB_USER='${{ secrets.DB_USER }}' | |
export DB_PASSWORD='${{ secrets.DB_PASSWORD }}' | |
export ALLOWED_HOSTS='${{ secrets.ALLOWED_HOSTS }}' | |
export SECRET_KEY='${{ secrets.SECRET_KEY }}' | |
export DEBUG='${{ secrets.DEBUG }}' | |
export EMAIL_HOST_USER='${{ secrets.EMAIL_HOST_USER }}' | |
export EMAIL_HOST_PASSWORD='${{ secrets.EMAIL_HOST_PASSWORD }}' | |
export GOOGLE_CLIENT_ID='${{ secrets.GOOGLE_CLIENT_ID }}' | |
export GOOGLE_SECRET='${{ secrets.GOOGLE_SECRET }}' | |
export SUB_DOMAIN='${{ secrets.SUB_DOMAIN }}' | |
export CSRF_TRUSTED_ORIGINS=${{ secrets.CSRF_TRUSTED_ORIGINS }} | |
export USE_X_FORWARDED_HOST='${{ secrets.USE_X_FORWARDED_HOST }}' | |
git pull | |
pip3 install -r requirements.txt | |
python manage.py migrate | |
rm -r static | |
python manage.py collectstatic --no-input | |
gunicorn vr_club.wsgi:application --bind $SUB_DOMAIN:8000 --workers 3 --threads 2 --pid /tmp/gunicorn.pid --daemon | |
kill -HUP $(cat /tmp/gunicorn.pid) | |
sudo nginx -t | |
sudo service nginx restart | |
else | |
sudo apt-get update -y | |
sudo apt install -y nginx | |
cd /var/www/ | |
git clone https://github.com/RezenkovD/vr-club.git | |
cd vr-club | |
sudo apt-get install -y python3.11-venv | |
python3.11 -m venv venv | |
source venv/bin/activate | |
export DB_HOST='${{ secrets.DB_HOST }}' | |
export DB_PORT='${{ secrets.DB_PORT }}' | |
export DB_NAME='${{ secrets.DB_NAME }}' | |
export DB_USER='${{ secrets.DB_USER }}' | |
export DB_PASSWORD='${{ secrets.DB_PASSWORD }}' | |
export ALLOWED_HOSTS='${{ secrets.ALLOWED_HOSTS }}' | |
export SECRET_KEY='${{ secrets.SECRET_KEY }}' | |
export DEBUG='${{ secrets.DEBUG }}' | |
export EMAIL_HOST_USER='${{ secrets.EMAIL_HOST_USER }}' | |
export EMAIL_HOST_PASSWORD='${{ secrets.EMAIL_HOST_PASSWORD }}' | |
export GOOGLE_CLIENT_ID='${{ secrets.GOOGLE_CLIENT_ID }}' | |
export GOOGLE_SECRET='${{ secrets.GOOGLE_SECRET }}' | |
export SUB_DOMAIN='${{ secrets.SUB_DOMAIN }}' | |
export CSRF_TRUSTED_ORIGINS=${{ secrets.CSRF_TRUSTED_ORIGINS }} | |
export USE_X_FORWARDED_HOST='${{ secrets.USE_X_FORWARDED_HOST }}' | |
sudo apt-get install -y libpq-dev python3-dev | |
sudo apt-get install -y build-essential | |
sudo apt-get install -y python3.11-dev | |
pip3 install -r requirements.txt | |
sudo apt-get update | |
sudo apt-get install postgresql postgresql-contrib -y | |
sudo service postgresql start | |
sudo -u postgres psql -c "CREATE DATABASE ${{ secrets.DB_NAME }};" | |
sudo -u postgres psql -c "ALTER USER ${{ secrets.DB_USER }} WITH PASSWORD '${{ secrets.DB_PASSWORD }}';" | |
sudo -u postgres psql -c "GRANT ALL PRIVILEGES ON DATABASE ${{ secrets.DB_NAME }} TO ${{ secrets.DB_USER }};" | |
python manage.py migrate | |
python manage.py collectstatic --no-input | |
yes | pip3 install gunicorn | |
cd vr-club | |
gunicorn vr_club.wsgi:application --bind $SUB_DOMAIN:8000 --workers 3 --threads 2 --pid /tmp/gunicorn.pid --daemon | |
echo "server { | |
listen 80; | |
server_name $ALLOWED_HOSTS; | |
location = /favicon.ico { access_log off; log_not_found off; } | |
location / { | |
proxy_pass http://$SUB_DOMAIN:8000; | |
proxy_set_header Host \$host; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
} | |
location /static/ { | |
alias /var/www/vr-club/static/; | |
} | |
location /media/ { | |
alias /var/www/vr-club/media/; | |
} | |
} | |
server { | |
listen 443; | |
server_name $ALLOWED_HOSTS; | |
ssl on; | |
ssl_certificate /var/www/certificate.crt; | |
ssl_certificate_key /var/www/private.key; | |
access_log /var/log/nginx/nginx.vhost.access.log; | |
error_log /var/log/nginx/nginx.vhost.error.log; | |
location / { | |
proxy_pass http://$SUB_DOMAIN:8000; | |
proxy_set_header Host \$host; | |
proxy_set_header X-Real-IP \$remote_addr; | |
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; | |
proxy_set_header X-Forwarded-Proto \$scheme; | |
} | |
location /static/ { | |
alias /var/www/vr-club/static/; | |
} | |
location /media/ { | |
alias /var/www/vr-club/media/; | |
} | |
}" > /etc/nginx/sites-available/vr-club | |
sudo ln -s /etc/nginx/sites-available/vr-club /etc/nginx/sites-enabled | |
sudo nginx -t | |
sudo service nginx restart | |
fi |