Automating ConvertKit Broadcasts with GitHub Actions
Creating the GitHub Actions Workflow
IIRC, all you've gotta do to get started is define a .github/workflows/main.yml
like the below at the root of your repository and set the workflow to be triggered by any push to the main branch (or whatever branch you'd like). Push it up to GitHub and head to the Actions tab on your GitHub repo home page and you should see some stuff starting to happen. Good deal.
name: Blog Update Notification
on:
push:
branches:
- main
# ...
Setting Up Your GitHub Repository
Next, define the job notify-subscribers
and make the first step checking out the repository so the workflow actually has access to the files. Use the sparse-checkout
feature to focus on only the specific directories we'll need (.github
for our workflow files/scripts and src/app/articles
for our posts). This optimizes the checkout process by ignoring irrelevant files, and might save a few microseconds or something.
Right after that step you're gonna need to install Node for what comes next, so slap that in there too:
# ...
jobs:
notify-subscribers:
runs-on: ubuntu-latest
steps:
- id: checkout_repository
name: Checkout repository
uses: actions/[email protected]
with:
sparse-checkout: |
.github
src/app/articles
sparse-checkout-cone-mode: false
- id: set_up_nodejs
name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '14'
# ...
Detecting Article Changes
Nice. Now getting a little meatier, the detect_article_changes
step executes a bash script that checks for modifications in your blog articles, ensuring only relevant changes trigger the subsequent steps.
# ...
- id: detect_article_changes
name: Detect article changes
run: bash ./.github/workflows/detect_article_changes.sh
# ...
I'm not going to go nuts breaking down the script, but I'll provide it for you here. You will likely need to customize it a bit for your setup, but it should be a good starting point. Don't forget to chmod +x
before pushing it up. The key lines are:
# ...
# Get the file changes in src/app/articles directory between the last two commits
changed_files=$(git diff --name-status HEAD^ HEAD -- 'src/app/articles' | grep -E '\.md$|\.mdx$' || true)
# ...
and:
# ...
# Get the date of the last commit
last_commit_date=$(git log -1 --format=%cd --date=short)
# ...
...because we'll only want to continue if there are changed_files
and the article_date
is later than or equal to the last_commit_date
(ignores updates to old articles; it shouldn't send out a notification for a fix to an ancient article).
Integrating ConvertKit and Sending Notifications
Last but not least we have this bad boy. This step is only executed if we've actually had an article meet our criteria (it's new) and we've set env.ARTICLE_DATA
previously with the post's metadata. After that, environment variables are set for integrating with ConvertKit's API: CK_API_KEY
is securely stored in GitHub secrets
, while the base URL and endpoint variables are defined in either regular old environment variables or repository vars
.
# ...
- id: send_ck_email
name: Send email via ConvertKit
if: ${{ env.ARTICLE_DATA }}
env:
ARTICLE_DATA: ${{ steps.detect_article_changes.outputs.article_data }}
CK_API_KEY: ${{ secrets.CK_API_KEY }}
CK_API_BASE_URL: ${{ vars.CK_API_BASE_URL }}
CK_API_BROADCASTS_ENDPOINT: ${{ vars.CK_API_BROADCASTS_ENDPOINT }}
run: bash ./.github/workflows/send_ck_email.sh
Here's that script. It's pretty straightforward and uses curl
to hit the endpoint with data pulled from the ARTICLE_DATA
environment variable. Gonna need to chmod +x
that one too.
Conclusion
And that's it for today. Using VS Code? Do yourself a favor and install the github.vscode-github-actions
extension to make viewing job status and setting variables a bit quicker right from within your editor.