Github: Automatically Deploy Files From One Repo to Another
Due to its rich and well designed API, Github has a vast number of integrations that run on top of it. Rultor is one of the many pieces of software that integrate with Github. If you’re not familiar with it, you can read more in several articles written by its creator here.
In this post I’m going to show you how to achieve one particular goal: moving files from one repo to another with Rultor. This is something that I did recently and figured I’d write about it, since I found it rather tricky.
Here’s a scenario: you have a repo where some javascript developers are building
something which will ultimately be turned into an awesome.min.js
file.
When you say "@rultor deploy"
, the file should be moved to the company.github.io
repo, because that repo is a website hosted by Github pages. This way, any page which includes that .js
file from the company’s website will always receive the latest version.
Sounds easy, so you write a deploy.sh
file for rultor to run on a deploy
command:
Inside .rultor.yml
you have:
This should work just fine, except the server doesn’t trust Github’s host, and you will see in rultor’s logs something like this:
If you use HTTPS, you will be prompted for the username and password.
You could, of course, find some way to automatically answer to the prompts. Maybe answer “Yes” to all the prompts that could occur, or, if you choose HTTPS, involve the credentials of someone with write access on that repo. None of the options is good, obviously.
The solution is Github’s Contents
API. Rultor will PUT
the file through the update
endpoint, using cURL
.
The steps are as follows:
- Get the API token
- Make a cURL
GET
to obtain the old file’s SHA - Encode the file to deploy using
openssl
- Make a cURL
PUT
with the message, the contents and the SHA
Let’s examine the steps more closely:
1. The API token
You don’t want the API token visible to everyone so, before uploading it
to Github, you encrypt it using the rultor
command-line tool:
Where company/developmentRepo
is the full name of the repo where the deployable is built. This is important, because it’s how rultor knows not to decrypt the files if they are found in another repository.
Then, inside .rultor.yml
you have
Getting the token in your script is the following line (rultor puts the resources under /home/r
)
2. Getting the old file’s SHA
Here you just make a cURL get, but you need to parse the JSON object that the Github API returns - I used jq for that.
Now the variable SHA_BUILD
will contain the required SHA. Needless to say, the first deployment will have to be
done manually in order for this script to work.
3. Encoding the content using openssl
The content of the deployed files has to be base64 encoded, as required by the Github API.
Note that I used awk here to remove newlines (otherwise the built JSON is not well formatted).
4. Make the cURL PUT request
This is a 2-step process:
- first, dump the json body in a file (becuase of the base64 content, which might be too large, cURL might complain if you specify it as an argument directly)
- make the request
See exactly how I did it all here. Also, see it in action here.
This is it. You can follow these steps to avoid blindly answering prompts, as well as involving actual user credentials. Any questions?