As part of the new Elixir School facelift we're splitting the Elixir Phoenix portion of the application out from the translated content. In order to continue down the path of CI/CD we needed to identify a way to trigger the deployment in one repo based on merges in another. We decided it was best to keep things inside GitHub Actions for now.
Out of the box GitHub does not provide an immediately obvious solution to this problem so after scouring the internet we were finally able to piece together a working solution which we'll document here today.
Before getting into the nuts and bolts let's review what we want to accomplish:
- For merges to school_house deploy to Production. This exists today via the deploy.yml workflow.
- Whenever changes are merged into the content repository, elixirschool, trigger the aforementioned deployment.
While GitHub may not provide a solution for this exact problem they do provide a robust API which has everything we'll need.
To achieve our goal we'll be relying on the workflow_dispatch
event.
Deployment Workflow
Let's start by updating our existing deployment workflow to work with this new event.
Thanks to the flexibility of GitHub Actions we won't need to make many changes to our existing deploy script.
The minimal change we can make here is adding workflow_dispatch
to the on:
configuration for our Workflow.
This tells GitHub that for any workflow_dispatch
, trigger this workflow, which is precisely what we need.
Let's update our deploy.yml
:
name: Deploy
on:
workflow_dispatch:
push:
branches:
- master
Here we're telling GitHub for any workflow_dispatch
and for pushes to master
we want to trigger this workflow, our deployment.
Personal Access Token
Before we can trigger our workflow_dispatch
even we'll need to generate a Personal Access Token to authenticate our request. Head over to the official GitHub document to see how to Create a personal access token.
We'll need to add this new token to our repository (or organization) secrets. For this example we'll call our secret ACCESS_TOKEN
.
With that in place we're ready to trigger the workflow
External Repository Worflow
We've updated our deployment workflow to listen to and trigger on the workflow_dispatch
event and we've setup our personal access token so now it's time to tie it all together with a simple cURL request:
curl -X POST \
-H "Authorization: Bearer ${{secrets.ACCESS_TOKEN}}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/<YOUR ORG>/<YOUR REPO>/actions/workflows/deploy.yml/dispatches \
-d '{"ref": "master"}'
We make an HTTP to the dispatches
endpoint of our workflow with our personal access token as the bearer token, the contents of the request body are not important here.
With a testing and working cURL command in place we need to create workflow file in our external repository to call it on merge:
---
name: Trigger Deploy
on:
push:
branches:
- master
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- run: |
curl -X POST \
-H "Authorization: Bearer ${{secrets.ACCESS_TOKEN}}" \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/<YOUR ORG>/<YOUR REPO>/actions/workflows/deploy.yml/dispatches \
-d '{"ref": "master"}'
That's it! When master
is pushed to we'll fire off our cURL request which will in turn trigger our other repository's deployment worflow.