Skip to content

Commit

Permalink
Fix bug 1407532: Fix "Deploy to Heroku" button (#735)
Browse files Browse the repository at this point in the history
* Update version of buildpack for git submodules
* Add SITE_URL setting to app.json and mark as required
* Remove code responsible for automatic discovery of SITE_URL after a
  deploy on Heroku
* Add runtime.txt and set python2 as the default for python buildpack
  • Loading branch information
Jarek authored and mathjazz committed Oct 16, 2017
1 parent 6dbddb8 commit 5d4f671
Show file tree
Hide file tree
Showing 8 changed files with 35 additions and 81 deletions.
10 changes: 7 additions & 3 deletions app.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"keywords": ["l10n", "localization", "mozilla", "collaboration", "python", "django"],
"website": "https://pontoon.mozilla.org",
"logo": "https://pontoon.mozilla.org/static/img/logo.svg",
"success_url": "/heroku-setup/",
"success_url": "/",
"image": "heroku/python",
"addons": [
{
Expand Down Expand Up @@ -32,6 +32,10 @@
}
],
"env": {
"SITE_URL": {
"description": "Base URL of the site. Has to be https://{app-name}.herokuapp.com.",
"required": true
},
"ADMIN_EMAIL": {
"value": "pontoon@example.com",
"description": "Email address for the ``ADMINS`` setting."
Expand Down Expand Up @@ -109,7 +113,7 @@
},
"buildpacks": [
{
"url": "https://github.com/dmathieu/heroku-buildpack-submodules#b37ffe4361bb9c975dd8e93068c9d296365d748c"
"url": "https://github.com/dmathieu/heroku-buildpack-submodules#0caf30af7737bf1bc32b7aafc009f19af3e603c1"
},
{
"url": "https://github.com/Osmose/heroku-buildpack-ssh"
Expand All @@ -125,7 +129,7 @@
}
],
"scripts": {
"postdeploy": "./bin/heroku_postdeploy"
"postdeploy": "./bin/heroku_postdeploy && ./manage.py heroku_deploy_setup"
},
"formation": {
"worker": {
Expand Down
2 changes: 1 addition & 1 deletion bin/heroku_postdeploy
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ MEMCACHE_SERVER=$(echo $MEMCACHE_SERVERS | cut -f1 -d:)
MEMCACHE_PORT=$(echo $MEMCACHE_SERVERS | cut -f2 -d:)

# Sometimes Memcache server isn't available immediately.
# Synchronization of project will fail if memcached isn't accessible.
# project_sync will fail if memcached isn't accessible.
while ! nc -z -w5 $MEMCACHE_SERVER $MEMCACHE_PORT; do
echo Waiting for memcached at $MEMCACHE_SERVER:$MEMCACHE_PORT
sleep 0.1
Expand Down
25 changes: 25 additions & 0 deletions pontoon/base/management/commands/heroku_deploy_setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os

from urlparse import urlparse, urljoin

from django.core.management.base import BaseCommand
from django.contrib.sites.models import Site

from pontoon.base.models import Project, User


class Command(BaseCommand):
help = 'Setup an instance of Pontoon deployed via Heroku Deploy.'

def handle(self, *args, **options):
site_url = os.environ.get('SITE_URL')
app_host = urlparse(site_url).netloc
admin_email = os.environ.get('ADMIN_EMAIL')
admin_password = os.environ.get('ADMIN_PASSWORD')

User.objects.create_superuser(admin_email, admin_email, admin_password)
Site.objects.filter(pk=1).update(name=app_host, domain=app_host)

Project.objects.filter(slug='pontoon-intro').update(
url=urljoin(site_url, 'intro/')
)
18 changes: 0 additions & 18 deletions pontoon/base/middleware.py
Original file line number Diff line number Diff line change
@@ -1,28 +1,10 @@
from django.conf import settings
from django.contrib import auth
from django.contrib.sites.models import Site
from django.shortcuts import redirect
from django.core.exceptions import PermissionDenied
from django.http import Http404, HttpResponseForbidden
from raygun4py.middleware.django import Provider


class HerokuDemoSetupMiddleware(object):
"""
Forces user to setup demo instance during the initial state.
There's a chance that user will try to open newly created instance by
typing an url in the browser window. That's why we have to ensure
that setup view is called as the first view.
"""

def process_request(self, request):
path = request.path
current_domain = Site.objects.get(pk=1).domain

if settings.HEROKU_DEMO and path != '/heroku-setup/' and current_domain == 'example.com':
return redirect('pontoon.heroku_setup')


class RaygunExceptionMiddleware(Provider):
def process_exception(self, request, exception):
# Ignore non-failure exceptions. We don't need to be notified
Expand Down
32 changes: 0 additions & 32 deletions pontoon/base/views.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import logging
import os

from bulk_update.helper import bulk_update
from datetime import datetime

from django.conf import settings
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.contrib.sites.models import Site
from django.core.cache import cache
from django.core.paginator import Paginator, EmptyPage
from django.db import transaction
from django.db.models import Q
Expand Down Expand Up @@ -75,34 +71,6 @@ def home(request):
return translate(request, locale, project.slug, path)


def heroku_setup(request):
"""
Heroku doesn't allow us to set SITE_URL or Site during the build phase of an app.
Because of that we have to set everything up after build is done and app is
able to retrieve a domain.
"""
app_host = request.get_host()
homepage_url = 'https://{}/'.format(app_host)
site_domain = Site.objects.get(pk=1).domain

if not os.environ.get('HEROKU_DEMO') or site_domain != 'example.com':
return redirect(homepage_url)

admin_email = os.environ.get('ADMIN_EMAIL')
admin_password = os.environ.get('ADMIN_PASSWORD')

User.objects.create_superuser(admin_email, admin_email, admin_password)
Site.objects.filter(pk=1).update(name=app_host, domain=app_host)

Project.objects.filter(slug='pontoon-intro').update(
url='https://{}/intro/'.format(app_host)
)

# Clear the cache to ensure that SITE_URL will be regenerated.
cache.delete(settings.APP_URL_KEY)
return redirect(homepage_url)


# TRANSLATE VIEWs


Expand Down
21 changes: 1 addition & 20 deletions pontoon/settings/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,25 +64,7 @@ def path(*args):

APP_URL_KEY = 'APP_URL'

# For the sake of integration with Heroku, we dynamically load domain name
# From the file that's set right after the build phase.
if os.environ.get('HEROKU_DEMO') and not os.environ.get('SITE_URL'):
def _site_url():
from django.contrib.sites.models import Site
from django.core.cache import cache

app_url = cache.get(APP_URL_KEY)

# Sometimes data from cache is flushed, We can't do anything about that.
if not app_url:
app_url = "https://{}".format(Site.objects.get(pk=1).domain)
cache.set(APP_URL_KEY, app_url)

return app_url

SITE_URL = lazy(_site_url, str)()
else:
SITE_URL = os.environ.get('SITE_URL', 'http://localhost:8000')
SITE_URL = os.environ.get('SITE_URL', 'http://localhost:8000')

# Custom LD_LIBRARY_PATH environment variable for SVN
SVN_LD_LIBRARY_PATH = os.environ.get('SVN_LD_LIBRARY_PATH', '')
Expand Down Expand Up @@ -165,7 +147,6 @@ def _site_url():
'sslify.middleware.SSLifyMiddleware',
'pontoon.base.middleware.RaygunExceptionMiddleware',
'pontoon.base.middleware.BlockedIpMiddleware',
'pontoon.base.middleware.HerokuDemoSetupMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
Expand Down
7 changes: 0 additions & 7 deletions pontoon/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.contrib.auth.views import logout
from django.views.generic import RedirectView, TemplateView

from pontoon.base.views import heroku_setup
from pontoon.intro.views import intro
from pontoon.teams.views import team

Expand Down Expand Up @@ -83,12 +82,6 @@
url(r'^404/$', TemplateView.as_view(template_name='404.html')),
url(r'^500/$', TemplateView.as_view(template_name='500.html')),

# Urls related to integration with Heroku
url(
r'^heroku-setup/', heroku_setup,
name='pontoon.heroku_setup'
),

# Robots.txt
url(
r'^robots.txt$',
Expand Down
1 change: 1 addition & 0 deletions runtime.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
python-2.7.14

0 comments on commit 5d4f671

Please sign in to comment.