Hold on Cowboy
This blog post is pretty old. Be careful with the information you find in here. The Times They Are A-Changin'
You find yourself using S3 for your static frontend code and using CloudFront to serve out that static content. Here is a handy script to deploy and invalidate old versions.
#!/bin/bash
CURR_COMMIT=$(git rev-parse HEAD);
CURR_VERSION=$(node -e "console.log(require('./package.json').version);");
VER_HASH=$(git rev-list -n 1 v$CURR_VERSION);
# Don't want to redo version bump
if [ $CURR_COMMIT == $VER_HASH ]
then
echo 'Already up to date'
exit
fi
npm version patch;
NEW_VERSION=$(node -e "console.log(require('./package.json').version);");
echo $NEW_VERSION;
git push origin head;
npm run buildprod
aws s3 sync ./public s3://www.example.com --size-only --delete;
# Invalidate cache
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths "/*";
What Does It Do?
This script will bump the current version of the project, build your static site, upload to AWS S3 bucket, then tell Cloudfront to invalidate all the files in the specific Cloudfront distribution.
What You’ll Need
To run this you’ll need a few things in place
- You need the AWS CLI. You can installed this with Brew
brew install awscli
, npmnpm install -g aws-cli
, or just from their site https://aws.amazon.com/cli/ - After you have AWS CLI installed, then you need to configure it. This requires putting the file
~/.aws/credentials
in place with your creds. Read More - You will need git installed.
- For this script we use npm.
Let’s Walk Through Each Part
CURR_COMMIT=$(git rev-parse HEAD);
CURR_VERSION=$(node -e "console.log(require('./package.json').version);");
VER_HASH=$(git rev-list -n 1 v$CURR_VERSION);
Here we are gathering a few details. We want to know the latests commit hash. Then we pull the version from the package.json
file and use that to look up the commit hash of the tag. When we use npm version patch
, it creates a semver tag like v1.3.1
.
# Don't want to redo version bump
if [ $CURR_COMMIT == $VER_HASH ]
then
echo 'Already up to date'
exit
fi
Here we check if the tag hash is different than the current HEAD hash. Basically we don’t want to create another commit if nothing new has been committed. You need to actually change code and make a new commit before this script will continue past this part.
npm version patch;
NEW_VERSION=$(node -e "console.log(require('./package.json').version);");
echo $NEW_VERSION;
git push origin head;
Here we tell NPM to bump the patch version up one. It will change the package.json
file version, make a commit, then create a git tag with that version. After we bump the version, we retrieve the version from package.json
like we did earlier and echo that new version out. Then we push this new commit and tag up to our git server (Github, GitLab, Bitbucket, etc).
npm run buildprod
aws s3 sync ./public s3://www.example.com --size-only --delete;
Here we build our static site files. In this case I’m using NPM to fire off a Webpack configuration to build my files. Then we use the AWS CLI to sync our files to S3. We basically tell it to delete all the files on the server that are not local and only use size as a comparison indicator.
# Invalidate cache
aws cloudfront create-invalidation \
--distribution-id YOUR_DISTRIBUTION_ID \
--paths "/*";
After we’ve done uploading our files to S3, we tell Cloudfront to invalidate all our files. Since this is a wild card, we only get dinged for one cache invalidation from Cloudfront rather than the hundreds or thousands of files that are on our site (that could get expensive, since Cloudfront starts charging for invalidations past 1000/month)
Summary
This script makes it really easy for me to just fire and forget and it has a little built in safe check so I’m not just bumping up the version with no new code to show for it. I’ve gotten in the habit to create a publish.sh
for many of my projects since I’m not always sure how each are deployed if I only deploy on occasion. Happy Shipping.