Bitrise's GitHub integration via OAuth is fast and easy to set up. However, I wanted to avoid giving Bitrise the ability to read and edit all of my public and private repos, both for my personal account as well as my organization's account. My goal was to use GitHub's Deploy Keys feature, which allows one to use a SSH key to scope access from outside parties to a single repo, and limit that access to Read or Write.
Guest post by John Turner.
John Turner is the FrontEnd Team Lead at Bento for Business (https://bentoforbusiness.com), a FinTech startup based in San Francisco. He's currently living in Chicago, IL where he works heavily in React and React Native, and has a passion for all things DevOps.
What I Wanted to Accomplish and Why
At Bento for Business we try to limit our data exposure to third parties as much as possible. While Bitrise's GitHub OAuth connection is fast and easy to implement, it's quite far-reaching in permissions that it requires from an organization. This is totally understandable, as getting read/write access to all of your public and private repos greatly reduces the possibility for connection issues, greasing the skids for developers to get up and running with Bitrise. However, most organizations would hesitate at giving that level of access to a third party. We were no different: if the OAuth flow was the only way to connect our code to Bitrise, it would be a nonstarter at Bento.
Thankfully, there's a great solution provided by Bitrise that's just a little harder to find.
How I Did It
Using the "Manual Connection" flow, Bitrise can provide an SSH keypair for you to use in your GitHub repo. Here are the steps needed to accomplish this:
- In the "Add an App" flow, when prompted for connecting to your repo, select the "Manual Connection" option, rather than the "GitHub Connection" option
- In a different browser tab, navigate to your GitHub repo that you wish to connect, and copy the SSH-based URL for cloning the repo
- Paste the copied URL into the field under the "Manual Connection" tab.
- In the "Setup Repository Access" step, select the option for manually setting up the SSH key access. This will then present you with the public SSH key.
- Copy this key and paste it into the Deploy Keys section of your repo's Settings in GitHub, making sure to not select "Grant Write Access to this Key".
Working with Git Submodules or Multiple Repos
In case you want to connect Bitrise to multiple repos with the same SSH key, or if your project uses Git Submodules (no judgement here, sometimes you need to!), you'll need to take a couple more steps. It turns out there's a major flaw in GitHub's Deploy Keys feature: one SSH key can only be used in a single repo. If you attempt to paste the same public SSH key into the Deploy Keys section of another repo, GitHub will respond with an error, saying that the key is already in use.
In the case of working with Git Submodules, this is a major issue, as Bitrise won't be able to pull your code from GitHub without also pulling the submodules, which it doesn't have access to.
In order to get around this, follow these steps:
- Remove the SSH key that you got from Bitrise from the Deploy Keys section of the original repo.
- Create a new GitHub user called something like MyOrgBitrise.
- Add the public SSH key to this new GitHub user's SSH keys settings.
- [Optional if the repo in question is part of a GitHub organization] In order to not give access to all of your organization's repos to this new user, add the newly-created GitHub user manually to the specific repos that want to link to Bitrise as a Collaborator with read-only access. Note: If you add this user to your GitHub organization, rather than manually as a Collaborator, your organization will be charged for this user, and it will be granted at least read-only access to all of your organization's codebases.
Adding Ability to Send GitHub Status Checks without OAuth Flow
Connecting to Bitrise so that it can pull your code is one thing; however, you'll probably want it to send back information to GitHub about your build's status in order to enforce PR requirements or see if your code actually compiles. Bitrise provides a great way to do this without needing to opt-in to their GitHub OAuth flow through their GitHub Status Check step that you can add to your workflow.
To accomplish this, you'll need to go through the steps listed above in the "Multiple Repos" section, wherein you create a new GitHub user, and add them as a read-only collaborator to your repository.
Once you've finished the above steps, here's what you'll do to allow for sending back status checks:
- Log into GitHub with your Bitrise bot account
- Navigate to Settings > Developer Settings > Personal Access Tokens
- Generate an access token, giving the token the repo/repo:status scope, and a note about what it's going to be used for. Make sure you copy it after generating it, as once you navigate away, you can't ever see it again.
- Log out of the Bitrise bot account in GitHub, and log into your normal developer account that has access to update the collaborators in your repo
- Change the access for the Bitrise bot account to Write
- Note: This is needed in order to allow the token the access that it needs to update the build status for a given PR
- Log into your Bitrise account and open your app that you've created
- Navigate to the workflow editor, and select the workflow that you want to report back to your GitHub repo
- Add the GitHub Status Check step to the beginning of your workflow (after the Register SSH Key step) and configure it like so:
- Make sure that "Run if previous step failed" is set to true
- Add your token to the step's config. You'll notice that doing this leverages Bitrise's Secrets platform, for storing sensitive data and injecting it into the workflow via environment variables.
- Note: You're going to need to check the box that says something like "Expose for Pull Requests" if you want to be able to show the build status on PRs. This can be slightly risky (according to Bitrise, "anyone might be able to do a workaround and log the value of secrets with a pull request, thus we advise not to expose secrets in PRs"); however since the token is only limited to updating the repo build status, and it's only scoped to the repos that the collaborator has access to, it's a fairly small risk area.
- Change the value for the Set Specific Status option to pending. This will send a status update to GitHub to mark your PR as currently building when the build begins
- Duplicate this step, and move the second copy to the very end of your workflow
- Leave the final copy of the GitHub Status Check the same, except that you should switch the Set Specific Status value back to auto for the final version, which will send either a success or failure back to GitHub depending on your build's outcome
And that's it! You should have build status checks sent back to GitHub without needing to use Bitrise's OAuth flow.
Bitrise has totally revolutionized how Bento develops and delivers mobile applications. I'm very grateful to the Bitrise team for not only developing a great platform for mobile DevOps, but also for providing secure ways to connect to your codebases. I hope this was helpful to anyone looking to start integrating with Bitrise for personal or professional projects.