Documentation
Set up GitHub Actions deploy workflows
A release uses the GitHub Actions workflows of your repository. This guide gives a setup with a staging and a production environment that Rondar can run from start to end.
Know how Rondar uses your workflows
Your workflows need no special input, secret or script for Rondar. Rondar never writes a workflow directly to your default branch: when it adds a workflow, it opens a pull request that you review and merge. A release does three things with GitHub Actions:
- It waits for the checks on the pull requests that it opens.
- It finds your deploy workflows by their names.
- After each merge, it follows the run of the deploy workflow for the merge commit. A run that ends with success is a completed deployment. A run that fails starts a repair.
Thus a repository that already tests its pull requests and deploys from a branch is almost ready. The steps below make each part clear.
Let Rondar find what is missing
Rondar reads your repository and shows what a release still needs:
- On Home, under "Waiting for you", a project that cannot release yet has the item Not ready to release.
- On the Releases tab of the project, the card Get ready to release has one line for each part: the check on pull requests, and the deploy step (or, for a mobile project, the mobile release workflows).
- On the New release page, the same card shows when a release cannot start.
- Under the pull request of a session, a line tells you when the repository does not test pull requests.
- In the project settings, Releases shows every line. Select Check again after you change the workflows.
For a missing check or a deploy workflow that is missing or needs a change, select Set up with an agent. Rondar starts a session. Its agent reads the repository, finds the test command or the deploy command, and writes the workflow for your project. The session opens a pull request like all other sessions. A new check runs on its own pull request, so you see that it works before you merge it.
The agent also makes what the deploy needs, so you do not do it by hand:
- It makes a missing
productionorstagingbranch from your default branch. - It makes each GitHub Actions secret that the workflows read: passwords, signing keys, encryption keys and the SSH deploy key. Rondar makes each value on its server and writes it to GitHub. Nobody sees a value: not you, not the agent, and not the session transcript.
- It adds the public deploy key to the server, through the SSH servers that you added to Rondar.
- It runs the deploy workflows, reads their logs, and fixes each failure until the deploy passes.
Rondar cannot get the first access to a server by itself. Before a deploy setup starts, Rondar looks for the deploy hosts in your deployment targets and in the Kamal files config/deploy*.yml. When no SSH server of yours reaches a host, Rondar asks you to add one, and the setup starts after that. The agent asks you only for a credential of another service (for example a Fly.io token) or for a decision.
A setup with no file change completes only when the last run of each deploy workflow passed. When the pull request adds the workflows, the first deploy starts when you merge it.
For a mobile project, Add the release workflows opens a pull request with the reviewed mobile release workflows. A release trusts only the exact reviewed files, so no agent writes them.
If you do not want an agent, Add a simple deploy workflow in the release settings opens a pull request with a deploy workflow that you complete by hand. You can also write the files yourself, as the steps below show.
Choose the branches
Rondar reads your branches and decides the route of a release. Choose one of these layouts:
| Layout | Staging deploys from | Production deploys from |
|---|---|---|
| Staging and production | Your default branch, for example main |
A branch with the name production |
| Production only | No staging | Your default branch |
The first layout is the most usual, and the examples below use it. In that layout a release goes into main, your staging environment gets it, and then Rondar opens the pull request from main into production.
If your repository has no production branch yet, make it from the default branch:
git fetch origin
git push origin origin/main:refs/heads/production
The default branch of a release is the Default Branch in the settings of the project. If that field is empty, it is the default branch of the repository.
Add a check for pull requests
A release must have one check or more, or it does not start. The simplest check is a workflow that runs your tests on each pull request.
# .github/workflows/ci.yml
name: CI
on:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run the tests
run: ./bin/test # Put your test command here.
Do not limit pull_request to one branch. A release opens pull requests into your default branch and into your production branch, so let the check run on both.
Rondar also uses the status checks that a branch protection rule requires.
Add the staging deploy workflow
This workflow deploys each push to the default branch.
# .github/workflows/deploy-staging.yml
name: Deploy staging
on:
push:
branches: [main]
workflow_dispatch:
concurrency:
group: deploy-staging
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
run: ./bin/deploy staging # Put your deploy command here.
env:
DEPLOY_TOKEN: ${{ secrets.STAGING_DEPLOY_TOKEN }}
- name: Check that the site answers
run: curl --fail --retry 5 --retry-delay 5 https://staging.example.com/
Add the production deploy workflow
This workflow deploys each push to the production branch.
# .github/workflows/deploy-production.yml
name: Deploy production
on:
push:
branches: [production]
workflow_dispatch:
concurrency:
group: deploy-production
cancel-in-progress: false
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy
run: ./bin/deploy production # Put your deploy command here.
env:
DEPLOY_TOKEN: ${{ secrets.PRODUCTION_DEPLOY_TOKEN }}
- name: Check that the site answers
run: curl --fail --retry 5 --retry-delay 5 https://www.example.com/
For a repository with production only, keep one deploy workflow and let it run on a push to the default branch.
Deploy with Vercel, Netlify, Render or Railway
Some platforms deploy each push to your default branch through their own GitHub app, with no workflow in your repository. Vercel, Netlify, Render, Railway and Cloudflare Pages do this. They also report each deploy to GitHub as a deployment.
When your repository has no deploy workflow, Rondar reads these deployments. If one of the newest deployments is a production deployment, a release does these steps after it merges into your default branch:
- It waits for the platform's production deployment of the merge commit.
- A deployment that ends with success completes the release.
- A deployment that fails starts a repair. The repair session gets the words and the log link of the platform.
Rondar takes a deployment as production when GitHub marks it as production, or when its environment name has the word production and not the word preview. If the platform deploys more than one service from the repository, Rondar follows the environment of the newest production deployment.
The platform must deploy production from your default branch. A deploy workflow in the repository always wins: Rondar then follows the workflow, not the platform.
An admin turns this on with the feature flag Platform deployments. When it is off, a release of such a repository ends at the merge.
Name the workflows so that Rondar finds them
Rondar looks at the file path and at the name of each active workflow.
- A deploy workflow has the word
deploy,deployment,releaseorpublishin its path or its name. - The staging workflow is the deploy workflow with
stagingin its path or its name. - The production workflow is the deploy workflow with
productionin its path or its name. If no workflow has that word, it is the one deploy workflow that is not the staging workflow.
There must be exactly one workflow for staging and exactly one for production. Two workflows with production in their names stop the release.
Use hyphens in file names: deploy-staging.yml. In deploy_staging.yml the underscore joins the two words, so set the name to Deploy staging if you keep such a file name.
Rondar treats each workflow with one of the deploy words as a deploy workflow. Keep those words out of the path and the name of other workflows, such as a test workflow. Names such as CI or Tests are safe.
Give each deploy workflow a trigger
After a merge, Rondar looks for the run of the deploy workflow for the merge commit.
- If the workflow has a
pushtrigger for the branch, GitHub starts the run and Rondar follows it. - If it has no such trigger but has
workflow_dispatch, Rondar starts the run one time on the branch. This works only when the workflow has no input that is required without a default value.
A workflow with no one of these triggers stops the release.
Make the result of the run true
Rondar reads the result of the run and nothing else. Make sure that the result tells the truth:
- Let the job fail when the deploy command fails. Do not hide an error with
|| trueorcontinue-on-error. - End the job with a request to the deployed site, as in the examples. A deploy that completes but gives a broken site is then a failed run, and Rondar starts a repair.
- Use a
concurrencygroup so that two deployments to the same environment do not run at the same time.
Let the release merge
A release merges its pull requests by itself. A branch rule that requires an approving review stops this: nobody approves the pull request, so it cannot merge. Rondar tells you before the release starts.
Remove the required approval from the branches that a release merges into, which are your default branch and your production branch. You can keep the required status checks. Your review of the work is the review of each session's pull request, before you select it for a release.
The GitHub account that the project owner connected must have permission to push and to merge in the repository.
Add more checks
Some checks do not run on pull requests, for example an end-to-end test that you start by hand. To make such a workflow necessary for each release, open the project settings, then Releases, then Additional release checks. Write one line for each workflow, with its trigger and its full path:
workflow_dispatch .github/workflows/e2e.yml
push .github/workflows/build.yml
Select Save release checks. Leave the field empty when you need no more checks.
Correct a release that does not start or stops
| Message | What to do |
|---|---|
| Release checks aren't set up yet. | Add a workflow that runs on pull_request, or a required status check. |
| Rondar could not find a production deploy workflow. | Give the production workflow a path or a name with deploy and production. |
| More than one workflow could be the production deploy. | Rename the workflows so that only one has production in its path or its name. The same applies to staging. |
| The production branch does not exist on GitHub. | Make the production branch, or let the production workflow run on a push to the default branch. |
| The staging branch and the production branch are the same. | Let the staging workflow and the production workflow run on different branches. |
| The deploy workflow does not run when the branch changes. | Add a push trigger for that branch, or workflow_dispatch without required inputs. |
| GitHub asks for an approving review before anything merges. | Remove the required approval from that branch. |
Some messages tell you to make a choice in Settings. The correction is in the repository: the names, the triggers and the branches, as this guide shows them. After the correction, start a new release with the same pull requests.
Do the first release
Start a session with a small change, wait for its pull request, and ship it alone. Ship a release gives the steps. Watch the timeline: each step that passes confirms one part of this setup.