Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simpler Cypress Setup #150

Merged
merged 8 commits into from Feb 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
52 changes: 12 additions & 40 deletions .github/workflows/cypress.yml
@@ -1,42 +1,18 @@
name: Cypress Tests
on:
workflow_call:
secrets:
CYPRESS_TEST_USER_PASS:
required: true
on: [deployment_status]

jobs:
Setup:
if: github.event.deployment_status.state == 'success'
paribaker marked this conversation as resolved.
Show resolved Hide resolved
runs-on: ubuntu-latest
steps:
- uses: jwalton/gh-find-current-pr@v1
id: findPr
- name: Set URL for Staging
if: github.ref_name == 'main'
run: echo "BASE_URL=https://tn-spa-bootstrapper-staging.herokuapp.com/" >> $GITHUB_ENV
- name: Set URL for PR
if: success() && steps.findPr.outputs.number
run: echo "BASE_URL=https://tn-spa-bootstrapper-pr-${PR}.herokuapp.com/" >> $GITHUB_ENV
env:
PR: ${{ steps.findPr.outputs.pr }}
- name: Raise for error
if: env.BASE_URL == ''
run: exit 1
- name: Raise for maintenance mode
run: |
html_body=$(curl ${{ env.BASE_URL }})
if echo $html_body | grep -q "Offline for Maintenance";
then
exit 1
else
echo "NOT in maintenance. Likely Heroku trigger after successful deploy";
fi
- name: Checkout
uses: actions/checkout@v2
- uses: actions/checkout@v2
- run: pipx install pipenv
- uses: actions/setup-python@v2
with:
python-version: '3.10'
cache: 'pipenv'
# Can't use cache because of https://github.com/actions/cache/issues/319
# cache: 'pipenv'
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

caching doesn't work for deployment_status events sadly. (known bug)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a big deal at the moment ? No right our apps arent that big that it would mean a huge slow down?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not really a big deal but it will add time to the test running. So if you push one final commit to the bootstrapper you'll need to wait an extra minute or so.

This does NOT impact the generated projects so definitely not a huge deal in my mind.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahhh okay good call out!

- name: Install bootstrapper dependencies
run: pipenv install --dev --deploy
- run: |
Expand All @@ -47,14 +23,11 @@ jobs:
name: my_project
path: my_project/
retention-days: 1
outputs:
BASE_URL: ${{ env.BASE_URL }}
Chrome:
needs: Setup
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/checkout@v2
- uses: actions/download-artifact@v3
with:
name: my_project
Expand All @@ -64,7 +37,7 @@ jobs:
NPM_CONFIG_PRODUCTION: false
working-directory: ./my_project/client
run: npm install
- name: Run against ${{ needs.Setup.outputs.BASE_URL }}
- name: Run against ${{ github.event.deployment_status.environment_url }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the jwalton/gh-find-current-pr@v1 action dependency as we no longer need to "figure out" what the URL is for the deployment. Heroku gives that to as when it creates the status event.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is why the Setup step above is now a LOT simpler

uses: cypress-io/github-action@v4
with:
working-directory: my_project/client
Expand All @@ -73,16 +46,15 @@ jobs:
NPM_CONFIG_PRODUCTION: false
CYPRESS_TEST_USER_EMAIL: "cypress@example.com"
CYPRESS_TEST_USER_PASS: ${{ secrets.CYPRESS_TEST_USER_PASS }}
CYPRESS_baseUrl: ${{ needs.Setup.outputs.BASE_URL }}
CYPRESS_baseUrl: ${{ github.event.deployment_status.environment_url }}
Firefox:
needs: Setup
runs-on: ubuntu-latest
container:
image: cypress/browsers:node16.14.2-slim-chrome103-ff102 # https://github.com/cypress-io/cypress-docker-images/tree/master/browsers
options: --user 1001
steps:
- name: Checkout
uses: actions/checkout@v2
- uses: actions/checkout@v2
- uses: actions/download-artifact@v3
with:
name: my_project
Expand All @@ -92,7 +64,7 @@ jobs:
NPM_CONFIG_PRODUCTION: false
working-directory: ./my_project/client
run: npm install
- name: Run against ${{ needs.Setup.outputs.BASE_URL }}
- name: Run against ${{ github.event.deployment_status.environment_url }}
uses: cypress-io/github-action@v4
with:
working-directory: my_project/client
Expand All @@ -101,4 +73,4 @@ jobs:
NPM_CONFIG_PRODUCTION: false
CYPRESS_TEST_USER_EMAIL: "cypress@example.com"
CYPRESS_TEST_USER_PASS: ${{ secrets.CYPRESS_TEST_USER_PASS }}
CYPRESS_baseUrl: ${{ needs.Setup.outputs.BASE_URL }}
CYPRESS_baseUrl: ${{ github.event.deployment_status.environment_url }}
36 changes: 4 additions & 32 deletions .github/workflows/heroku_deploy.yml
Expand Up @@ -4,6 +4,7 @@ jobs:
Setup:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: jwalton/gh-find-current-pr@v1
id: findPr
- name: Set app_name for Staging
Expand All @@ -13,46 +14,17 @@ jobs:
run: echo "APP_NAME=tn-spa-bootstrapper-pr-${PR}" >> $GITHUB_ENV
env:
PR: ${{ steps.findPr.outputs.pr }}
outputs:
APP_NAME: ${{ env.APP_NAME }}
Maintenance-On:
needs: Setup
runs-on: ubuntu-latest
steps:
- name: Turn Maintenance Mode On for ${{ needs.Setup.outputs.APP_NAME }}
run: |
echo "Turning on maintenance so Cypress status starts as failing until rerun happens later."
heroku maintenance:on --app=${{ needs.Setup.outputs.APP_NAME }}
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
Cypress:
needs: Maintenance-On
uses: ./.github/workflows/cypress.yml
secrets:
CYPRESS_TEST_USER_PASS: ${{ secrets.CYPRESS_TEST_USER_PASS }}
Maintenance-Off:
if: ${{ always() }}
needs: [Setup, Cypress]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Turn Maintenance Mode Off for ${{ needs.Setup.outputs.APP_NAME }}
run: |
echo "Turning off maintenance so Heroku triggering rerun of Cypress will succeed";
heroku maintenance:off --app=${{ needs.Setup.outputs.APP_NAME }}
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
- name: Update Heroku on what type of app to build next time (Vue or React)
run: |
config_file=$(./scripts/vue_or_react.sh)
current_config=$(heroku config:get BUILDPACK_RUN --app=${{ needs.Setup.outputs.APP_NAME }})
current_config=$(heroku config:get BUILDPACK_RUN --app=${{ env.APP_NAME }})
if echo "$current_config" | grep -q "config_file"; then
echo "Keeping current config of $config_file"
else
echo "Switching Heroku to build with $config_file instead"
heroku plugins:install heroku-builds
heroku builds:cache:purge --app=${{ needs.Setup.outputs.APP_NAME }} --confirm=${{ needs.Setup.outputs.APP_NAME }}
heroku config:set BUILDPACK_RUN="pipenv run cookiecutter . --config-file $config_file --no-input -f" --app=${{ needs.Setup.outputs.APP_NAME }}
heroku builds:cache:purge --app=${{ env.APP_NAME }} --confirm=${{ env.APP_NAME }}
heroku config:set BUILDPACK_RUN="pipenv run cookiecutter . --config-file $config_file --no-input -f" --app=${{ env.APP_NAME }}
fi
env:
HEROKU_API_KEY: ${{ secrets.HEROKU_API_KEY }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This Github Action used to do 2 things:
1 - Tell Heroku if it needs to build a Vue app or a React app
2 - Trigger Cypress and cause it to fail early so...(blah blah complicated logic that doesn't exist anymore)

Now all this action does is detect if the dev has touched more React files or more Vue files, and then tell Heroku to change it's build type if a change is needed.

I still don't love that this runs on EVERY commit. I may try to do something smarter, but thats a future PR.

52 changes: 10 additions & 42 deletions {{cookiecutter.project_slug}}/.github/workflows/cypress.yml
@@ -1,44 +1,13 @@
name: Cypress Tests
on:
workflow_call:
secrets:
CYPRESS_TEST_USER_PASS:
required: true
on: [deployment_status]

jobs:
Setup:
runs-on: ubuntu-latest
steps:
- uses: jwalton/gh-find-current-pr@v1
id: findPr
- name: Set URL for Staging
if: github.ref_name == 'main'
run: echo "BASE_URL=https://{{ cookiecutter.project_slug }}-staging.herokuapp.com/" >> $GITHUB_ENV
- name: Set URL for PR
if: success() && steps.findPr.outputs.number
run: echo "BASE_URL=https://{{ cookiecutter.project_slug }}-pr-${PR}.herokuapp.com/" >> $GITHUB_ENV
env:
PR: {{ "${{ steps.findPr.outputs.pr }}" }}
- name: Raise for error
if: env.BASE_URL == ''
run: exit 1
- name: Raise for maintenance mode
run: |
html_body=$(curl {{ "${{ env.BASE_URL }}" }})
if echo $html_body | grep -q "Offline for Maintenance";
then
exit 1
else
echo "NOT in maintenance. Likely Heroku trigger after successful deploy";
fi
outputs:
BASE_URL: {{ "${{ env.BASE_URL }}" }}
Chrome:
needs: Setup
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Run against {{ "${{ needs.Setup.outputs.BASE_URL }}" }}
- uses: actions/checkout@v2
- name: Run against {{ "${{ github.event.deployment_status.environment_url }}" }}
uses: cypress-io/github-action@v4
with:
working-directory: client
Expand All @@ -47,17 +16,16 @@ jobs:
NPM_CONFIG_PRODUCTION: false
CYPRESS_TEST_USER_EMAIL: "cypress@example.com"
CYPRESS_TEST_USER_PASS: {{ "${{ secrets.CYPRESS_TEST_USER_PASS }}" }}
CYPRESS_baseUrl: {{ "${{ needs.Setup.outputs.BASE_URL }}" }}
CYPRESS_baseUrl: {{ "${{ github.event.deployment_status.environment_url }}" }}
Firefox:
needs: Setup
if: github.event.deployment_status.state == 'success'
runs-on: ubuntu-latest
container:
image: cypress/browsers:node16.14.2-slim-chrome103-ff102 # https://github.com/cypress-io/cypress-docker-images/tree/master/browsers
options: --user 1001
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Run against {{ "${{ needs.Setup.outputs.BASE_URL }}" }}
- uses: actions/checkout@v2
- name: Run against {{ "${{ github.event.deployment_status.environment_url }}" }}
uses: cypress-io/github-action@v4
with:
working-directory: client
Expand All @@ -66,4 +34,4 @@ jobs:
NPM_CONFIG_PRODUCTION: false
CYPRESS_TEST_USER_EMAIL: "cypress@example.com"
CYPRESS_TEST_USER_PASS: {{ "${{ secrets.CYPRESS_TEST_USER_PASS }}" }}
CYPRESS_baseUrl: {{ "${{ needs.Setup.outputs.BASE_URL }}" }}
CYPRESS_baseUrl: {{ "${{ github.event.deployment_status.environment_url }}" }}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the comments I made above for the bootstrappers cypress.yml are relevant here as well

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

buuut....since this file is even simpler now, we don't even need a Setup step anymore

43 changes: 0 additions & 43 deletions {{cookiecutter.project_slug}}/.github/workflows/heroku_deploy.yml

This file was deleted.

1 change: 0 additions & 1 deletion {{cookiecutter.project_slug}}/.gitignore
Expand Up @@ -4,7 +4,6 @@
node_modules/
server/static/
server/media-files/
package-lock.json

# Byte-compiled / optimized / DLL files
__pycache__/
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/Procfile
Expand Up @@ -14,6 +14,6 @@ web: gunicorn {{ cookiecutter.project_slug }}.wsgi --chdir=server --log-file -
# 3. Up-to-date build numbers shown in app (ideally auto-generated at build-and-deploy time)
#
# Comment the line below to disable migrations automatically after a Heroku push.
release: python server/manage.py makemigrations --noinput && python server/manage.py migrate --noinput && ./scripts/release.sh
release: python server/manage.py makemigrations --noinput && python server/manage.py migrate --noinput


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about test data? should that not get triggered?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test data gets run once during review app creation. That happens in a different place than this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

python3 server/manage.py create_test_data

db_setup is what triggers test data to be created.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

which is called from the postdeploy Heroku step.

"postdeploy": "./scripts/db_setup.sh"

That step only ever gets triggered during review app creation and thus never runs on staging or prod.
Which is why for brand new projects you have to run some of these commands manually once against staging.

4 changes: 0 additions & 4 deletions {{cookiecutter.project_slug}}/README.md
Expand Up @@ -4,10 +4,6 @@

## Setup

### Github & Heroku
1. [Generate an auth token for Heroku](https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-authorizations-create) and add it to the [repo secrets](https://docs.github.com/en/actions/security-guides/encrypted-secrets) as `HEROKU_API_KEY` so Github Actions can reach Heroku. `heroku authorizations:create -d "Github Actions" -s write-protected`
1. [Generate an auth token for Github](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-authentication-to-github#authenticating-with-the-api) and add it as [an environment variable](https://devcenter.heroku.com/articles/config-vars) as `GITHUB_TOKEN` so Heroku can trigger Github Actions

### Docker
If this is your first time...
1. [Install Docker](https://www.docker.com/)
Expand Down
2 changes: 1 addition & 1 deletion {{cookiecutter.project_slug}}/scripts/deploy-on-heroku.sh
Expand Up @@ -3,7 +3,7 @@
# Deploy {{cookiecutter.project_name}} To heroku
# NOTE: This script is intended to deploy the app for the first time to heroku
# if you run it again make and the app is aleady created on heroku make sure to comment lines 6:29
APP_NAME={{ cookiecutter.project_slug }}-staging.herokuapp.com
APP_NAME={{ cookiecutter.project_slug|replace('_', '-') }}-staging.herokuapp.com
heroku login --interactive
heroku create $APP_NAME --buildpack heroku/python
heroku addons:create heroku-postgresql:mini --app $APP_NAME
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heroku requires that our URLs use - instead of _. Our slugs are the opposite (to be Pythonic).
Annoying and an issue you run into if you bootstrap a project from scratch that has a space in it's name.
The fix isn't always obvious. But I think this is now a solved problem.

Expand Down
5 changes: 0 additions & 5 deletions {{cookiecutter.project_slug}}/scripts/release.sh

This file was deleted.

This file was deleted.

Expand Up @@ -420,7 +420,7 @@
# Popular testing framework that allows logging to stdout while running unit tests
TEST_RUNNER = "django_nose.NoseTestSuiteRunner"

CORS_ALLOWED_ORIGINS = ["https://{{ cookiecutter.project_slug }}-staging.herokuapp.com", "https://{{ cookiecutter.project_slug }}.herokuapp.com"]
CORS_ALLOWED_ORIGINS = ["https://{{ cookiecutter.project_slug|replace('_', '-') }}-staging.herokuapp.com", "https://{{ cookiecutter.project_slug|replace('_', '-') }}.herokuapp.com"]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above. Heroku requires -

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldnt be an issue when we remove heroku default in the BS

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, hopefully we can find a way to have separate heroku scripts set values like these for the project based on what was actually created in heroku. Obviously this code is effectively guessing what the URL will be (in a deterministic, but fragile way)

{% if cookiecutter.client_app.lower() != 'none' -%}
CORS_ALLOWED_ORIGINS.append("http://localhost:8089")
{% endif -%}
Expand Down