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.