-
Notifications
You must be signed in to change notification settings - Fork 9
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
Cypress release trigger #99
Conversation
f8dba45
to
7748924
Compare
CYPRESS_TEST_USER_EMAIL: | ||
required: true | ||
CYPRESS_TEST_USER_PASS: | ||
required: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
workflow_call
means it's called my other workflows (instead of on code push).
As a result, it doesn't have its own env or secrets so those have to be passed explicitly.
exit 1 | ||
else | ||
echo "NOT in maintenance. Likely Heroku trigger after successful deploy"; | ||
fi |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Test the URL to see if the app is not up yet (first commit) or if the app is in maintenance mode (waiting on deploy to finish)
path: my_project/ | ||
retention-days: 1 | ||
outputs: | ||
BASE_URL: ${{ env.BASE_URL }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
upload-artifacts
allows us to do all the work we needed to do for cookiecutter only once. The later workflows can then do things like run inside a docker container and not worry about pip missing or not having permissions to install things (problem I ran into)
- uses: actions/download-artifact@v3 | ||
with: | ||
name: my_project | ||
path: my_project/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only step needed to get the results of building code out during Setup
- uses: actions/download-artifact@v3 | ||
with: | ||
name: my_project | ||
path: my_project/ | ||
- name: Install frontend dependencies | ||
env: | ||
NPM_CONFIG_PRODUCTION: false | ||
working-directory: ./my_project/client | ||
run: npm install |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But for some reason npm install
during Setup
wouldn't work. Didn't bother digging into why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it was a react app then it could be due to that Apollo
peer dependencies error that is also behind the ESLint tests failing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It was on a Vue app. I think the error was something about the lock file missing. Something not getting carried over during the upload/download artifact step. I'm not really worried, though I like the idea of doing all the build steps during setup only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I understand this better now. Makes perfect sense now that I think about.
Storing artifacts via actions/upload-artifact
is only for files and folders. For things like installs via apt/python/npm there is a separate caches
github action (actions/cache
) which is also available inside actions like actions/setup-python
(which we use). That is the proper way to install something once, and then reuse it between jobs or even separate workflow runs.
You can in fact install something when running the main
branch and it'll use that cache by default on PRs.
artifacts are less powerful and are attached to a specific workflow run. So they can't be reused more widely.
with: | ||
working-directory: my_project/client | ||
browser: chrome | ||
headless: true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no longer a thing. It's headless by default. Use headed
to actually have a browser available.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Firefox should now be more stable when it runs. (lots of questions/confusion/complaints online about running Firefox with Cypress. Hopefully this fix holds for a while)
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 }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On every push of code we'll now immediately:
- Put the app in maintenance mode
- Run Cypress expecting it to fail fast (otherwise it'll be hidden on the PR and it won't exist to be re-run later)
- Turn maintenance mode off
@@ -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 | |||
release: python server/manage.py makemigrations --noinput && python server/manage.py migrate --noinput && ./scripts/release.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When Heroku is finished deploying it'll call this new shell script
@@ -4,6 +4,10 @@ | |||
|
|||
## 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) 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) so Heroku can trigger Github Actions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Heroku auth token is easy to generate and lives forever. Adding it to Github settings is safe as well.
The Github auth token is currently a personal auth token of mine (Ed) with an expiration in a week or so. That could be a long-lived token, but it also required authing the token with JumpCloud. Not sure how long that lives for. PLUS, you then add that token to Heroku and all devs can see it, so not as safe.
I did look into a solution for that. Github Actions DOES generate a temporary app token while the workflows are running and I was able to pass that to Heroku using the Heroku CLI (same spot where we turn maintenance mode on). Problem is that the token gets expired when the workflow finishes. Seems like the only way around that is to keep the workflow alive....so then we're back to sleeping for 5min.
|
||
workflow_id = self.find_cypress_workflow_id(branch) | ||
job_id = self.find_job_id_for_cypress_step(workflow_id) | ||
self.rerun_job(job_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A little complicated/convoluted, but basically we call Github's API to find the most recent Cypress run on this PR and tell it to run again.
At this point deployment is finished so rerunning will not only pass, but Cypress will be testing the most recently version of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🚀 🚀 🎸 ✅
Future me here 👋 |
Better way to run Cypress for Review Apps
Addresses #88
TODO:
NPM_PRIVATE_TOKEN
from Github and Heroku settingsGITHUB_TOKEN
and add it to the pipeline and staging settings in HerokuHEROKU_API_KEY
and replace the old one in Github settings