The slack-ruby-client generates code from an API reference scraped from the Slack documentation website. Until now, the update process was a manual operation involving checking out the code, running a rake
task, updating a CHANGELOG.md
, and making a pull request, e.g. slack-ruby-client#455.
Let’s automate this using GitHub Actions (GHA)! We’ll need some advanced token-fu to auto-trigger CI.
A basic job that runs on cron, daily at 11:15PM.
Scope permissions to r/w access to repo contents and pull requests.
Check-out the code, and run the rake
task that updates the API.
Create a pull request with the changes.
This works, but does not trigger CI. This is by design, because GITHUB_TOKEN
is not allowed to.
To trigger CI we need a different token. You can create a personal access token (PAT), but that would run CI under your account, which may exclude you from approving PRs because of branch protection rules. A better solution is to use a token from an org-owned GitHub app. I created one called “Slack Ruby CI Bot”, and gave it r/w permissions for “Contents” and “Pull Requests”, then installed it in the slack-ruby GitHub org and noted the installation ID. I also generated a new private key from the bottom of the app settings page and set two repo secrets: CI_APP_ID
to the value of the app ID, and CI_APP_PRIVATE_KEY
for the contents of the private key from the .pem
file downloaded from GitHub.
Get the the app token in GHA.
Use it in the pull request GHA, with a fallback to GITHUB_TOKEN
for testing the GHA in my fork.
Now that PRs trigger CI, and commits are made by slack-ruby-ci-bot
, let’s update CHANGELOG.md
with the PR number output by the create-pull-request
action. A text search-and-replace will do.
We can amend the previous pull request and force-push the change back to GitHub. To authenticate to GitHub using the above-mentioned token we generate a base64-encoded BASIC auth x-access-token:token
header, then stuff it into all HTTP requests made by git
. This is what the create-pull-request
action actually does in code, too.
Bonus features include getting the current date and the git commit of the updated submodule that contains the API reference to make the CHANGELOG and the commit messages pretty.
The final result is here and you can see it in action in slack-ruby-client#465.