I have a gitub.io repo which hosts my webpage -- the source for that webpage (uncompiled Jade / Sass code) is in a separate public repo. Travis-CI is set up to watch my source repo for changes and run the compile suite, generating the HTML/CSS that will get pushed to the github.io repo.
Can I set up Travis to automatically do a push to a github repo I own if the compile passed, without hard-coding my username and password into my .travis.yml
file (obviously this is a security concern)?
I've seen this question, but it wasn't answered with Travis in mind -- I don't think I can use keypair authentication because I'd need to put the private key in the repo or in the travis script, which is just as big a security hole as putting in my password.
For anyone else who winds up here, I found the following information using roidrage's answer as a springboard:
Travis uses public/private key encryption to allow you to embed sensitive information in a .travis.yml
file. You can install their gem called "travis" and use it to encrypt stuff, and they'll decrypt it securely on their end. Documentation: http://docs.travis-ci.com/user/encryption-keys/
On github, you can generate a "personal access token" in your applications settings. This can be used like a password by applications. Encrypt that using the above technique and throw it in your yaml.
This can be achieved by storing a token to access GitHub in an encrypted way in the .travis.yml file. See our docs for examples on how to encrypt data.
As for the push to GitHub Pages, there's a blog post summing up the steps quite well, and it even points to a script that you can use in your build.
A mirror of the script is here:
#!/usr/bin/env bash
# This script was written to facilitate the deployment process of Pelican
# websites using Travis CI. See this blog post for more information:
# http://kevinyap.ca/2014/06/deploying-pelican-sites-using-travis-ci/
usage="Usage: $(basename "$0") (deploy | diff | serve)
Commands:
deploy Upload site to Github Pages
diff Compare locally generated site to live site
serve Generate and serve site (auto-reloads on changes)"
TARGET_REPO="iKevinY/iKevinY.github.io"
GH_PAGES_BRANCH="master"
DEVELOP_CONF="pelicanconf.py"
PUBLISH_CONF="publishconf.py"
OUTPUT_DIR="output"
REMOTE_DIR="remote"
PY_CMD="python3"
SERVER="http.server"
PORT="8000"
rootPath="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
generate_site() {
# Based on http://zonca.github.io/2013/09/automatically-build-pelican-and-publish-to-github-pages.html
if [ "$TRAVIS" == "true" ]; then
# Ensure that builds triggered by pull requests are not deployed
if [ "$TRAVIS_PULL_REQUEST" != "false" ]; then
echo "Successfully built pull request #$TRAVIS_PULL_REQUEST."
exit 0
fi
echo "Deploying site to $GH_PAGES_BRANCH branch of $TARGET_REPO."
git config --global user.email "travis@travis-ci.org"
git config --global user.name "Travis CI"
else
cd "$rootPath" || exit 1
pelican -s $PUBLISH_CONF
fi
# Pull hash and commit message of the most recent commit
commitHash=$(git rev-parse HEAD)
commitMessage=$(git log -1 --pretty=%B)
# Clone the GitHub Pages branch and rsync it with the newly generated files
GITHUB_REPO=https://${GH_TOKEN:-git}@github.com/${TARGET_REPO}.git
git clone --branch $GH_PAGES_BRANCH --depth 1 "$GITHUB_REPO" $REMOTE_DIR &> /dev/null
rsync -r --exclude=.git --delete $OUTPUT_DIR/ $REMOTE_DIR/
pushd $REMOTE_DIR > /dev/null
git add -A
git status -s
$1 # execute the function that was passed as an argument
}
push_changes() {
if [ "$TRAVIS" == "true" ]; then
longMessage="Generated by $commitHash; pushed by build #$TRAVIS_BUILD_NUMBER."
git commit -m "$commitMessage" -m "$longMessage"
git push origin $GH_PAGES_BRANCH &> /dev/null || echo "Push failed."
else
read -rp "Push changes to GitHub Pages? [y/N] " response
if [[ "$response" =~ ^[Yy]$ ]]; then
git commit -m "$commitMessage" -m "Generated by $commitHash."
git push origin $GH_PAGES_BRANCH
fi
popd > /dev/null
rm -rf -- $REMOTE_DIR $OUTPUT_DIR && echo "Removed $REMOTE_DIR and $OUTPUT_DIR."
fi
}
case "$1" in
'deploy')
generate_site push_changes
;;
'diff')
generate_site 'git --no-pager diff --cached --color-words'
;;
'serve')
developPath=${rootPath}/develop
local_ip=$(ifconfig | grep 'inet ' | awk 'NR==2 {print $2}')
# Seed directory with site content
cd "$rootPath" && pelican -s $DEVELOP_CONF > /dev/null
echo "Serving HTTP at $(tput bold)${local_ip}:${PORT}$(tput sgr0)."
cleanup() {
pkill -f $SERVER
cd "$rootPath" && rm -r "$developPath" && echo && exit 0
}
trap cleanup SIGINT
(pelican -rs $DEVELOP_CONF 2> /dev/null) &
(cd "$developPath" || exit 1; $PY_CMD -m $SERVER $PORT 1> /dev/null) &
wait
;;
*)
echo "$usage"
exit 2
;;
esac
Mac OS El Capitan requires Ruby ^2.2
brew unlink ruby; brew install Ruby
gem install travis
Use the travis gem to encrypt your secret PAT and update your .travis.yml
travis encrypt GH_TOKEN=<secret github personal access token> --add