Hi Michael,
This is a pretty common question that we’re getting and right now we don’t have a perfect answer but we do have some workarounds. Let me try and break it down.
Let’s start with talking about the staging environment.
The first question here, is what branch do you want deploying to your staging environment, I think the majority of folks would want it to be the master/main branch, ie the code that’s going to be deployed to production.
Master/Main Branch → Staging environment
Ok, so keeping our attention on the staging environment and our development cycle, it follows that work would be done in Pull requests and made against the master/main branch so that preview environments are created.
previewEnabled: true
And once those PRs are merged, we want the staging environment to autodeploy.
autoDeploy: true
To demonstrate this, I’ve created a very simple example at GitHub - johnbeynonorg/render-devcycle-example with the render.yaml looking like:
previewsEnabled: true
services:
- type: web
name: my-amazing-app
plan: free
env: ruby
autoDeploy: true # this is the default but included for explicitness
buildCommand: ./render-build.sh
startCommand: ./render-start.sh
A behaviour I’m using here which we’ll come back to later is described in Blueprint Specification | Render - I’m not specifying a branch or repo attribute - which means that when we create the blueprint we would use the repo that the render.yaml is located in and the branch the PR is for s deployed.
Continuining on and deploying this to us as a new Blueprint,
and here’s the results of this https://my-amazing-app.onrender.com/
So that’s our staging environment setup.
A quick PR against the repo Some new work by johnbeynon · Pull Request #1 · johnbeynonorg/render-devcycle-example · GitHub
and here’s the results of that in a preview environment, https://my-amazing-app-pr-1.onrender.com/
So at this point, we’ve now got:
- A separate staging environment that autodeploys master
- Preview environments
But what about production?
If we had our production service set to auto deploy master, then at this point we may have deployed master to production - which isn’t what you want.
Bear with me. It’s not a great story right now but it’s something we’re blissfully aware of and have plans to address this.
Create a new repo to house just a render.yaml file (no other files required) like GitHub - johnbeynonorg/render-devcycle-example-prod - the render.yaml here looks very similar to the previous one:
services:
- type: web
name: my-amazing-app-production
repo: https://github.com/johnbeynonorg/render-devcycle-example
plan: free
env: ruby
autoDeploy: false
buildCommand: ./render-build.sh
startCommand: ./render-start.sh
except notice that here that I’ve given the app a new name to clearly identify it as production, I’m actually explicitly setting the repo to the original repo path, disabled previewEnvironments and disabling auto deployments.
Here’s the example repo:
https://github.com/johnbeynonorg/render-devcycle-example-prod
So now, I create a new blueprint pointing at this repo
and here’s the result - https://my-amazing-app-production.onrender.com
Notice, that’s deploying the master branch - because again, that’s the branch the render.yaml is on (even though it’s a different repo). With autodeploy set to false that means to put anything into production you either need to:
- A manual deploy needs to be done from the Render dashboard
- Deploy hook for the service is hit (Deploy Hooks | Render · Cloud Hosting for Developers)
- A deploy is triggered via the API Trigger a deploy
So that’s our environments setup, what does our flow look like?
- Developer checks out code and creates a branch
- Code, code, code
- Developer submits a PR
- Preview environment is created
- PR to closed and merged
- Preview environment is deleted
- staging autodeploys master
- …
- …
- Production is manually deployed using method above
Whilst the additional repo is a tad clunky right now, it does have some added advantages in that you can have render.yaml in both repo’s - the different environments can have different environment variables different plans etc
Could you do all of this without a separate repo?
Yes you could. It definitely gets a little tricky as you have to be careful about merging changes made to the render.yaml between branches. You’d also have to have a separate branch for ‘production’ so the flow would be:
GitHub repo with develop and master branch - names are up to you. You can change the github default branch to ‘develop’ as well if that helps.
PRs are made against the develop branch - when closed the ‘develop’ branch is auto deployed to the staging environment. Then, when develop is merged into master then the master branch could be autodeployed (as it’s a separate branch now) or manually deployed as detailed above.
Whilt the separate repo for production is a little odd, it keeps things a little bit simpler and actually the method I prefer for my own flow as it means I’m in control when code is deployed to production. Obviously, if you want to run a fully automated deploy process then you’d have to go with this second flow but be aware of the limitations right now.
I hope that helps,
Regards,
John B