Skip to content
This repository was archived by the owner on Jan 28, 2022. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# Webpack deploy utilities
Collection of useful utilities for deploying (not only) Webpack apps

## Deploy
Each deployment into Redis (`deploy-redis`) saves the `index.html` build file under a full SHA key of the current git commit. (e.g. `app:b45ab63a5aaafd35377ca571824e60fe07a52101`) and optionally updates the “tip” commit of a given branch (using the `--branch` argument). Updates to the branch tip are made by storing it’s revision and index under the `app:branch-revision:branchname` and `app:branch:branchname` respectively.

## Activation
There are two steps to activate a deployed build.
1. Activate branch: use `activate-branch --branch branchname` to activate this branch and set the current main build to the tip of this branch. All consecutive activations **inside this branch** will be automatically promoted as the main current build.
2. Activate a revision: use `activate-rev --branch branchname --rev SHA` to activate a given SHA revision inside a given branch and set the revision as the main current build **if that branch has been previously activated**.

## Installation
```
cd $YOUR_PROJECT
Expand Down
4 changes: 4 additions & 0 deletions bin/deploy-info
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/usr/bin/env node
var path = require('path');
require(path.join(__dirname, '..', 'tasks', 'deploy-info'));
require('gulp').start('deploy-info');
32 changes: 20 additions & 12 deletions bin/deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@
# dont execute next commands on error
trap 'exit' ERR

# colors
RED='\033[0;31m'
YELLOW='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# let echo interpret escape chars (\n)
shopt -s xpg_echo

GULP="`npm bin`/gulp"

if [[ ! -x "$GULP" ]]; then
echo "ERROR: gulp executable not found"
echo "${RED}ERROR: gulp executable not found$NC"
echo "Check path for valid executable: $GULP"
exit 1
fi
Expand All @@ -33,7 +39,7 @@ set_dirname
# ENV is the first parameter, defaults to "staging"
ENV=${1-development}

echo "Environment: $ENV"
echo "Environment: ${YELLOW}$ENV$NC"

case "$ENV" in
production)
Expand Down Expand Up @@ -62,17 +68,17 @@ BRANCH=`git rev-parse --abbrev-ref HEAD`
REV="$COMMIT"
BUILD_COUNT=`ls -a build*log 2>/dev/null | cat | wc -l | awk {'print $1'}`

if [ $BRANCH == "dev" -o $BRANCH == "master" -o $BRANCH == "HEAD" ]; then
echo "Deploying with commit hash $REV\n"
if [ $BRANCH == "HEAD" ]; then
echo "Deploying with commit hash ${YELLOW}$REV$NC\n"
else
REV="branch/$BRANCH"
echo "Deploying branch $BRANCH\n"
REV="$BRANCH"
echo "Deploying revision ${YELLOW}$COMMIT$NC for branch ${YELLOW}$BRANCH$NC\n"
fi

if [[ $BUILD_COUNT -ne 0 ]]; then
echo "Detected $BUILD_COUNT build app versions:"
echo "Detected $BUILD_COUNT build app versions from logs:"
for build in build*log; do
echo "\t`cat "$build" | grep Hash: | head -1 | cut -d' ' -f2`: `echo $build | cut -d'.' -f2`"
echo "\t${YELLOW}`grep Hash: "$build" | head -1 | cut -d' ' -f2`$NC: $build"
done
echo
else
Expand All @@ -85,7 +91,7 @@ gulp_config deploy-s3 --env=$ENV

gulp_config rollbar-source-map --env=$ENV --rev=$COMMIT_ROLLBAR

gulp_config deploy-redis --env=$ENV --rev=$REV
gulp_config deploy-redis --env=$ENV --rev=$COMMIT --branch=$BRANCH

gulp_config git-deploy-tag --env=$ENV --rev=$REV

Expand All @@ -95,6 +101,8 @@ gulp_config slack-notify --env=$ENV --rev=$REV
echo "\nDeploy into $ENV environment took ${SECONDS}s.\n"

echo "TEST with:"
echo "\t$DOMAIN/?rev=$REV"
echo "THEN to activate run:"
echo "\tactivate-rev --notify --env=$ENV --rev=$REV\n"
echo "\t$DOMAIN/?rev=$REV\n"
echo "To activate the branch (auto updated revision with every branch deploy):"
echo "\t${CYAN}activate-branch --env=$ENV --branch=$BRANCH --notify$NC\n"
echo "To activate the commit:"
echo "\t${CYAN}activate-rev --env=$ENV --rev=$COMMIT --branch=$BRANCH --notify$NC\n"
72 changes: 72 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"current-rev": "bin/current-rev",
"list-revs": "bin/list-revs",
"slack-notify": "bin/slack-notify",
"deploy-info": "bin/deploy-info",
"deploy-redis": "bin/deploy-redis",
"deploy-s3": "bin/deploy-s3",
"rollbar-source-map": "bin/rollbar-source-map",
Expand Down
14 changes: 14 additions & 0 deletions tasks/activate-rev.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ const {
const { notifyRevActivated } = require('./slack-notify');

async function updateMainRev(client, config, { rev, branch, majorRelease }) {
if (!config.indexKey) {
gutil.log(gutil.colors.red('No redis.indexKey set in config'));
return;
}
const file = await client.get(util.format(config.indexKey, rev));
if (!file) {
gutil.log(
Expand All @@ -23,6 +27,11 @@ async function updateMainRev(client, config, { rev, branch, majorRelease }) {
return;
}

if (!config.branchKey) {
gutil.log(gutil.colors.red('No redis.branchKey set in config'));
return;
}

gutil.log(
gutil.colors.yellow(env()),
'Activating rev',
Expand All @@ -35,6 +44,11 @@ async function updateMainRev(client, config, { rev, branch, majorRelease }) {
client.set(util.format(config.branchKey, branch), file);
await client.set(util.format(config.branchRevKey, branch), rev);

if (!config.mainBranchKey) {
gutil.log(gutil.colors.red('No redis.branchKey set in config'));
return;
}

const activeBranch = await client.get(config.mainBranchKey);

if (activeBranch === branch) {
Expand Down
60 changes: 60 additions & 0 deletions tasks/deploy-info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
const gulp = require('gulp');
const util = require('util');
const gutil = require('gulp-util');

const { env, getConfigFor, getRedisClient } = require('./utils');

async function deployBuildInfo(redisConfig, gitConfig) {
const client = await getRedisClient(redisConfig);
const currentBranch = await client.get(redisConfig.mainBranchKey);
const currentRev = await client.get(redisConfig.mainRevKey);
const lastBranchRevision = await client.get(
util.format(redisConfig.branchRevKey, currentBranch),
);

gutil.log(gutil.colors.yellow(env()), 'Info for', redisConfig.indexKey);

gutil.log(
gutil.colors.yellow(env()),
'\tActive branch:',
currentBranch ? gutil.colors.cyan(currentBranch) : gutil.colors.red('Not set'),
);
gutil.log(
gutil.colors.yellow(env()),
'\tActive revision:',
gutil.colors.cyan(currentRev),
);

// Safety check to make sure that branch deploy was properly activated as main
if (lastBranchRevision === currentRev) {
gutil.log(
gutil.colors.yellow(env()),
'\t✅ Tip of the active branch is the main revision',
);
}
// TODO: github diff link
// gutil.log(gutil.colors.yellow(env()), 'GitHub diff link: https://');

if (gitConfig.url) {
const link = gitConfig.url + '/?rev=' + currentRev;
gutil.log(gutil.colors.yellow(env()), '\tApp direct link:', link);
}

await client.quit();
}

async function deployInfo(redisConfig, gitConfig) {
await Promise.all(
(redisConfig.files || [redisConfig])
.map(async fileConfig =>
deployBuildInfo(Object.assign({}, redisConfig, fileConfig), gitConfig),
),
);
}

/**
* Deploy tasks
*/
gulp.task('deploy-info', async () =>
deployInfo(getConfigFor('redis'), getConfigFor('git')),
);
12 changes: 10 additions & 2 deletions tasks/deploy-redis.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,16 @@ async function uploadFile(config, file, rev, branch) {
await client.set(util.format(config.indexKey, rev), file);

if (branch) {
await client.set(util.format(config.branchKey, branch), file);
await client.set(util.format(config.branchRevKey, branch), rev);
if (!config.branchKey) {
gutil.log(gutil.colors.red('No redis.branchKey set in config'));
} else {
await client.set(util.format(config.branchKey, branch), file);
}
if (!config.branchRevKey) {
gutil.log(gutil.colors.red('No redis.branchRevKey set in config'));
} else {
await client.set(util.format(config.branchRevKey, branch), rev);
}
}

// Store timestamp information under 'app-timestamp:<rev-number>'
Expand Down