diff --git a/app.json b/app.json index 6ee211708b..b1be5a910e 100644 --- a/app.json +++ b/app.json @@ -4,49 +4,15 @@ "addons": [ "heroku-postgresql:hobby-dev" ], + "formation": { + "web": { + "quantity": 1 + } + }, "env": { - "HEROKU_APP_NAME": { - "required": true - }, "DJANGO_SECRET_KEY": { "generator": "secret" }, - "ASSET_DOMAIN": { - "required": true - }, - "AWS_ACCESS_KEY_ID": { - "required": true - }, - "AWS_LOCATION": { - "required": true - }, - "AWS_S3_CUSTOM_DOMAIN": { - "required": true - }, - "AWS_SECRET_ACCESS_KEY": { - "required": true - }, - "AWS_STORAGE_BUCKET_NAME": { - "required": true - }, - "GITHUB_TOKEN": { - "required": true - }, - "SLACK_WEBHOOK_RA": { - "required": true - }, - "USE_CLOUDINARY": { - "required": true - }, - "CLOUDINARY_CLOUD_NAME": { - "required": true - }, - "CLOUDINARY_API_KEY": { - "required": true - }, - "CLOUDINARY_API_SECRET": { - "required": true - }, "DEBUG": "False", "CORS_WHITELIST": "*", "XSS_PROTECTION": "True", diff --git a/docs/ops_heroku_settings.md b/docs/ops_heroku_settings.md index 5df473dd11..6b2fc787ee 100644 --- a/docs/ops_heroku_settings.md +++ b/docs/ops_heroku_settings.md @@ -18,11 +18,8 @@ Enable domain redirection by setting `DOMAIN_REDIRECT_MIDDLEWARE_ENABLED` to `Tr ## Special purposes Environment Variables -- `GITHUB_TOKEN`: GITHUB API authentication, -- `SLACK_WEBHOOK_RA`: Webhook to `mofo-review-apps` - `CORAL_TALK_SERVER_URL`: If Coral Talk commenting is to be enabled, set the server URL here. Don't forget to add the domain to your CSP directives for script-src and child-src - ## Cloudinary for Review Apps and Staging (BuyersGuide only) We use [Cloudinary's upload-mapping](https://cloudinary.com/documentation/django_image_and_video_upload#django_forms_and_models) feature to copy images from the production to the staging Cloudinary account. diff --git a/docs/workflow.md b/docs/workflow.md index ea6f774abe..5f19ed8817 100644 --- a/docs/workflow.md +++ b/docs/workflow.md @@ -41,10 +41,30 @@ Opening a PR activates different services: ### Review Apps -Opening a PR will automatically create a review app in the `foundation-site` pipeline. It's not possible to use OAuth but you can still access the admin interface with a username and password. The login details for review apps are published in the `mofo-ra-foundation` Slack channel when the app has finished deploying. +#### Review App for PRs + +Opening a PR will automatically create a Review App in the `foundation-site` pipeline. A slack bot posts credentials and links to Review Apps in to the `mofo-ra-foundation` Slack channel. + +*Note:* This only work for Mo-Fo staff: you will need to manually open a Review App on Heroku for PRs opened by external contributors. + +#### Review App for branches + +You can manually create a review app for any branch pushed to this repo. It's useful if you want to test your code on Heroku without opening a PR yet. + +To create one: +- log into Heroku. +- Go to the `foundation-site` pipeline. +- Click on `+ New app` and select the branch you want to use. + +The review app slack bot will post a message in the `foundation-site` with links and credentials as soon as the review app is ready. + +#### Environment variables: -Environment variable: - `REVIEW_APP`: set to True on review app. +- `GITHUB_TOKEN`: GITHUB API authentication, +- `SLACK_WEBHOOK_RA`: Webhook to `mofo-ra-foundation` + +Non-secret envs can be added to the `app.json` file. Secrets must be set on Heroku in the `Review Apps` (pipelines' `settings` tab). ### Continuous Integration testing diff --git a/network-api/networkapi/management/commands/review_app_admin.py b/network-api/networkapi/management/commands/review_app_admin.py index b5e7af853f..3b8020a75a 100644 --- a/network-api/networkapi/management/commands/review_app_admin.py +++ b/network-api/networkapi/management/commands/review_app_admin.py @@ -7,7 +7,6 @@ from factory import Faker from django.contrib.auth.models import User from django.conf import settings -import re import requests @@ -31,36 +30,55 @@ def handle(self, *args, **options): User.objects.create_superuser('admin', 'admin@example.com', password) reviewapp_name = settings.HEROKU_APP_NAME - m = re.search(r'\d+', reviewapp_name) - pr_number = m.group() + pr_number = settings.HEROKU_PR_NUMBER + branch_name = settings.HEROKU_BRANCH - # Get PR's title from Github - token = settings.GITHUB_TOKEN - org = 'mozilla' - repo = 'foundation.mozilla.org' - r = requests.get(f'https://api.github.com/repos/{org}/{repo}/pulls/{pr_number}&access_token={token}') - try: - pr_title = ': ' + r.json()['title'] - except KeyError: - pr_title = '' + # As of 01/2020 we can only get the PR number if the review app was automatically created + # (https://devcenter.heroku.com/articles/github-integration-review-apps#injected-environment-variables). + # For review app manually created, we have to use the branch name instead. + if pr_number: + # Get PR's title from Github + token = settings.GITHUB_TOKEN + org = 'mozilla' + repo = 'foundation.mozilla.org' + r = requests.get(f'https://api.github.com/repos/{org}/{repo}/pulls/{pr_number}&access_token={token}') + try: + pr_title = ': ' + r.json()['title'] + except KeyError: + pr_title = '' + + for l in r.json()['labels']: + if l['name'] == 'dependencies': + color = '#BA55D3' + break + else: + color = '#7CD197' + fallback_text = f'''New review app deployed: It will be ready in a minute!\n + PR {pr_number}{pr_title}\n + Login: admin\n + Password: {password}\n + URL: https://{reviewapp_name}.herokuapp.com''' + message_title = f'PR {pr_number}{pr_title}\n' + github_url = f'https://github.com/mozilla/foundation.mozilla.org/pull/{pr_number}' + github_button_text = 'View PR on Github' - for l in r.json()['labels']: - if l['name'] == 'dependencies': - color = '#BA55D3' - break else: color = '#7CD197' + fallback_text = f'''New review app deployed: It will be ready in a minute!\n + Branch: {branch_name}\n + Login: admin\n + Password: {password}\n + URL: https://{reviewapp_name}.herokuapp.com''' + message_title = f'Branch: {branch_name}\n' + github_url = f'https://github.com/mozilla/foundation.mozilla.org/tree/{branch_name}' + github_button_text = 'View branch on Github' slack_payload = { 'attachments': [ { - 'fallback': 'New review app deployed: It will be ready in a minute!\n' - f'PR {pr_number}{pr_title}\n' - f'Login: admin\n' - f'Password: {password}\n' - f'URL: https://{reviewapp_name}.herokuapp.com', + 'fallback': f'{fallback_text}', 'pretext': 'New review app deployed. It will be ready in a minute!', - 'title': f'PR {pr_number}{pr_title}\n', + 'title': f'{message_title}', 'text': 'Login: admin\n' f'Password: {password}\n', 'color': f'{color}', @@ -72,8 +90,8 @@ def handle(self, *args, **options): }, { 'type': 'button', - 'text': 'View PR on Github', - 'url': f'https://github.com/mozilla/foundation.mozilla.org/pull/{pr_number}' + 'text': f'{github_button_text}', + 'url': f'{github_url}' } ] } diff --git a/network-api/networkapi/settings.py b/network-api/networkapi/settings.py index d8dda4dbba..36d857e43b 100644 --- a/network-api/networkapi/settings.py +++ b/network-api/networkapi/settings.py @@ -49,6 +49,8 @@ FILEBROWSER_DIRECTORY=(str, ''), RANDOM_SEED=(int, None), HEROKU_APP_NAME=(str, ''), + HEROKU_PR_NUMBER=(str, ''), + HEROKU_BRANCH=(str, ''), NETWORK_SITE_URL=(str, ''), PETITION_TEST_CAMPAIGN_ID=(str, ''), PULSE_API_DOMAIN=(str, ''), @@ -134,6 +136,8 @@ USE_X_FORWARDED_HOST = env('USE_X_FORWARDED_HOST') HEROKU_APP_NAME = env('HEROKU_APP_NAME') +HEROKU_PR_NUMBER = env('HEROKU_PR_NUMBER') +HEROKU_BRANCH = env('HEROKU_BRANCH') if HEROKU_APP_NAME: herokuAppHost = env('HEROKU_APP_NAME') + '.herokuapp.com'