How to push to github from Travis CI
January 26, 2019
Use a github Deploy key, which is scoped to a single repo, instead of a Personal Access token, which has push rights to all your public repos.
This approach is only as secure as the private key that Travis creates for your github repo.
Approach from https://stackoverflow.com/a/22977235.
Software used for this HOWTO:
- OSX Mojave
- OpenSSH_7.9p1, LibreSSL 2.7.3
- travis gem 1.8.9
- openssl (LibreSSL 2.6.5)
Steps
1. Install Travis CI command-line client
$ gem install travis
...
$
2. Create a GitHub deploy key
$ cd ~/src/mycode/shmig
$ ssh-keygen -t rsa -b 4096 -C "mkbucc@gmail.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/mark/.ssh/id_rsa): ./travis_key
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ./travis_key.
Your public key has been saved in ./travis_key.pub.
...
$ cat travis_key.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQDCDzTsOqLcIm88P...
$
3. Add deploy key to your repo
GitHub -> your repository -> settings -> Deploy Keys -> "Add deploy key"
- Title = travis-ci
- Key = [paste public key generated in previous step]
- Allow write access = checked
4. Encode private key with big random password
$ password=$(openssl rand -hex 32)
$ cat travis_key | openssl aes-256-cbc -k "$password" -md sha256 -a > travis_key.enc
5. Give Travis access to the password
$ echo "" > .travis.yml
$ travis encrypt travis_key_password=$password --add env.matrix
Detected repository as mbucc/shmig, is this correct? |yes|
$ grep -A 2 ^env .travis.yml
env:
matrix:
secure: VBF7EjJ/e2ibYLpaURDrWnrMsTn0mBPPeJiNSaoqrB/Z6Kg54PF+nZiMzo0kL9y3yi8PKlmTvfG3uPx3N7tCuQDVehH47yeSozT2QX/Vbod3RObpUsETT8LbSgyDmgi2+F4aZzsY+MtkLnv28wvcMN2kM4HjGL/0ROKIDL15ChFsmvn+BA7yUnVm43vQJcYRRlxDDRSdofJBHxtguPWjOvK8ARF5hSML/kl3mZZTmPXOR2W/WxnQXNSHkgaAoir/3ElSGVVV1ipN1ifWNdzlJI8Tcod9cDNE0DscOqMWC/7V9mEZUosHBN4ZIrn84ijBuiKYoWMoN1M5TRXwIYxsKiLf9+IwqRHaV0Q36Ktkoj5j4CG4xOPeS+oVHkJ6vFptr3hzgWPcKzi5zGzS8dQfnbk3PmxXDJyt9S3eVpc7HVjWVU5rqgBI912Z/vhgK6pJ/txPVJDw67sgA8h8G4UtoqMJpBwST4BIyjO33BCvFUpMT8WloGRiPCMBSub8WAJTjZ7Cy3E6l/iSpBVTRvr6Gqb9f4of61MUOjKiUyrdG05g21sm/RlNNrm2lg5vgZjq8AsEnxlKn5ONHWJjspivBDgMUH7PN5F3e1ZRfd2AievtjQC5FS7wU2ogN74O3Bor5y0UgJPRRl0/YL5Z7xFOz7Eo3qvp9JRTTqobgIz33+A=
$
$
$ git add travis_key.enc
$ git commit -m 'Encrypted private key half of github deploy key.'
$ git add .travis.yml
$ git commit -a -m 'Add encrypted password that can decrypt private github deploy key.'
6. Setup private key for push to git
I added the following lines to my test runner script:
openssl aes-256-cbc -k "$travis_key_password" -d -md sha256 -a -in travis_key.enc -out travis_key
echo "Host github.com" > ~/.ssh/config
echo " IdentityFile $(pwd)/travis_key" >> ~/.ssh/config
chmod 400 travis_key
git remote set-url origin git@github.com:mbucc/shmig_test.git
echo "github.com ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==" > ~/.ssh/known_hosts
if ! git push -v ; then
_err "git push error"
fi
Stumbles along the way
1. digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539:
alpine:3.8|apk update|apk add|bash,sqlite|/bin/bash|sqlite3 [PASS] shmig-net bad decrypt 139902961870496:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:539: remote: Invalid username or password. fatal: Authentication failed for 'https://github.com/mbucc/shmig_test.git/' [Sat Jan 26 16:37:24 UTC 2019] git push error
I had forgotten to commit the .travis.yml, so the travis_key_password
variable was not in the Travis build environment. Doh!
Before I
The default digest was changed from MD5 to SHA256 in Openssl 1.1,
per https://stackoverflow.com/a/39641378.
realized this, I spent a good amount of time making sure the digest
used by my laptop openssl matched
the one used by the Travis build box openssl.
Hence the -md sha256
argument to openssl
in both environments.
2. remote: Invalid username or password
git remote set-url origin git@github.com:mbucc/shmig_test.git
This one took a long while to figure out. You must use the git URL for the remote in order for the SSH private key to work.
3. Permissions 0664 for '/home/travis/build/mbucc/shmig_test/travis_key' are too open.
chmod 400 ./travis_key
Tags: ci