Commit 6ae6d731 authored by Robert Knight's avatar Robert Knight

Create qa deployment of the client

Add a new build stage to Jenkins CI builds of the master branch which
deploys a "QA" build to S3. This QA build:

 - Has a pre-release version number of the form `X.Y.Z-{commit hash}`
 - Has a stable URL at https://cdn.hypothes.is/hypothesis@qa
   (as opposed to https://cdn.hypothes.is/hypothesis for the prod build)
 - Loads the sidebar app from qa-h (https://qa.hypothes.is/app.html)
 - Does not update the changelog or create a Git tag or GitHub release

This build is currently not deployed to npm at all, but we might need to
do that in future if we were to create a QA deployment of the browser
extension with it.

---

 - Add a QA deploy step to the Jenkins build.
 - Skip GitHub release creation and changelog updates for pre-release
   versions used for QA deployments.
 - Remove the preversion.sh script, which is no longer needed since the
   builds always run in Jenkins and not on a developer's system.
 - Support specifying the npm tag to check in `wait-for-npm-release.sh`,
   though this is not used in the final version of this commit.
parent dc514d39
...@@ -12,6 +12,9 @@ node { ...@@ -12,6 +12,9 @@ node {
// Git branch which releases are deployed from. // Git branch which releases are deployed from.
releaseFromBranch = "master" releaseFromBranch = "master"
// S3 bucket where the embedded client is served from.
s3Bucket = "cdn.hypothes.is"
// Pre-release suffix added to new package version number when deploying, // Pre-release suffix added to new package version number when deploying,
// eg. "testing". // eg. "testing".
// //
...@@ -31,6 +34,11 @@ node { ...@@ -31,6 +34,11 @@ node {
returnStdout: true returnStdout: true
).trim() ).trim()
lastCommitHash = sh (
script: 'git show HEAD --no-patch --format="%h"',
returnStdout: true
).trim()
if (lastCommitAuthor == "jenkins-hypothesis") { if (lastCommitAuthor == "jenkins-hypothesis") {
echo "Skipping build of automated commit created by Jenkins" echo "Skipping build of automated commit created by Jenkins"
return return
...@@ -65,6 +73,46 @@ node { ...@@ -65,6 +73,46 @@ node {
return return
} }
milestone()
stage('Publish to QA') {
qaVersion = pkgVersion + "-${lastCommitHash}"
nodeEnv.inside("-e HOME=${workspace}") {
withCredentials([
string(credentialsId: 'npm-token', variable: 'NPM_TOKEN'),
usernamePassword(credentialsId: 'github-jenkins-user',
passwordVariable: 'GITHUB_TOKEN_NOT_USED',
usernameVariable: 'GITHUB_USERNAME'),
[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 's3-cdn']
]) {
sh """
git config --replace-all user.email ${env.GITHUB_USERNAME}@hypothes.is
git config --replace-all user.name ${env.GITHUB_USERNAME}
"""
// Build a prerelease version of the client, configured to load
// the sidebar from the qa h deployment.
sh """
export SIDEBAR_APP_URL=https://qa.hypothes.is/app.html
yarn version --no-git-tag-version --new-version ${qaVersion}
"""
// Deploy to S3, so the package can be served by
// https://qa.hypothes.is/embed.js.
//
// If we decide to build a QA browser extension using the QA
// client in future then we will need to deploy to npm as well.
sh """
export AWS_ACCESS_KEY_ID=${env.AWS_ACCESS_KEY_ID}
export AWS_SECRET_ACCESS_KEY=${env.AWS_SECRET_ACCESS_KEY}
scripts/deploy-to-s3.js --bucket ${s3Bucket} --tag qa
"""
}
}
// Revert back to the pre-QA commit.
sh "git checkout ${lastCommitHash}"
}
milestone() milestone()
stage('Publish') { stage('Publish') {
input(message: "Publish new client release?") input(message: "Publish new client release?")
...@@ -82,15 +130,17 @@ node { ...@@ -82,15 +130,17 @@ node {
string(credentialsId: 'npm-token', variable: 'NPM_TOKEN'), string(credentialsId: 'npm-token', variable: 'NPM_TOKEN'),
usernamePassword(credentialsId: 'github-jenkins-user', usernamePassword(credentialsId: 'github-jenkins-user',
passwordVariable: 'GITHUB_TOKEN', passwordVariable: 'GITHUB_TOKEN',
usernameVariable: 'GITHUB_USERNAME')]) { usernameVariable: 'GITHUB_USERNAME'),
[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: 's3-cdn']
]) {
// Configure commit author for version bump commit and auth credentials // Configure commit author for version bump commit and auth credentials
// for pushing tag to GitHub. // for pushing tag to GitHub.
// //
// See https://git-scm.com/docs/git-credential-store // See https://git-scm.com/docs/git-credential-store
sh """ sh """
git config user.email ${env.GITHUB_USERNAME}@hypothes.is git config --replace-all user.email ${env.GITHUB_USERNAME}@hypothes.is
git config user.name ${env.GITHUB_USERNAME} git config --replace-all user.name ${env.GITHUB_USERNAME}
git config credential.helper store git config credential.helper store
echo https://${env.GITHUB_USERNAME}:${env.GITHUB_TOKEN}@github.com >> \$HOME/.git-credentials echo https://${env.GITHUB_USERNAME}:${env.GITHUB_TOKEN}@github.com >> \$HOME/.git-credentials
""" """
...@@ -113,17 +163,16 @@ node { ...@@ -113,17 +163,16 @@ node {
sh "echo '//registry.npmjs.org/:_authToken=${env.NPM_TOKEN}' >> \$HOME/.npmrc" sh "echo '//registry.npmjs.org/:_authToken=${env.NPM_TOKEN}' >> \$HOME/.npmrc"
sh "npm publish --tag ${npmTag}" sh "npm publish --tag ${npmTag}"
sh "scripts/wait-for-npm-release.sh" sh "scripts/wait-for-npm-release.sh"
// Deploy the client to cdn.hypothes.is, where the embedded
// client is served from by https://hypothes.is/embed.js.
sh """
export AWS_ACCESS_KEY_ID=${env.AWS_ACCESS_KEY_ID}
export AWS_SECRET_ACCESS_KEY=${env.AWS_SECRET_ACCESS_KEY}
scripts/deploy-to-s3.js --bucket ${s3Bucket}
"""
} }
} }
echo "Uploading package ${pkgName} v${newPkgVersion} to CDN"
// Upload the contents of the package to an S3 bucket, which it
// will then be served from.
docker.image('nickstenning/s3-npm-publish')
.withRun('', "${pkgName}@${newPkgVersion} s3://cdn.hypothes.is") { c ->
sh "docker logs --follow ${c.id}"
}
} }
} }
......
...@@ -4,6 +4,13 @@ set -eu ...@@ -4,6 +4,13 @@ set -eu
cd "$(dirname "$0")" cd "$(dirname "$0")"
# Skip GitHub release creation for QA releases.
is_prerelease=$(node -p "require('./package.json').version.includes('-')")
if [ $is_prerelease = "true" ]; then
echo "Skipping GitHub release creation for pre-release"
exit 0
fi
# nb. The remote refname is fully qualified because this script is run in a CI # nb. The remote refname is fully qualified because this script is run in a CI
# environment where not all heads may have been fetched. # environment where not all heads may have been fetched.
git push https://github.com/hypothesis/client.git HEAD:refs/heads/$BRANCH_NAME --follow-tags git push https://github.com/hypothesis/client.git HEAD:refs/heads/$BRANCH_NAME --follow-tags
......
#!/bin/sh
set -eu
# Check that tag creation works.
# The tag is not currently signed because Jenkins does not have this set up.
git tag --message "Dummy Tag" dummy-tag
git tag --delete dummy-tag > /dev/null
# Check GitHub API access token
CLIENT_INFO_URL=https://api.github.com/repos/hypothesis/client
REPO_TMPFILE=/tmp/client-repo.json
curl -s -H "Authorization: Bearer $GITHUB_TOKEN" $CLIENT_INFO_URL > $REPO_TMPFILE
CAN_PUSH=$(node -p -e "perms = require('$REPO_TMPFILE').permissions, perms && perms.push")
if [ "$CAN_PUSH" != "true" ]; then
echo "Cannot push to GitHub using the access token '$GITHUB_TOKEN'"
exit 1
fi
...@@ -48,4 +48,9 @@ ${changelist} ...@@ -48,4 +48,9 @@ ${changelist}
fs.writeFileSync(changelogPath, updatedChangelog); fs.writeFileSync(changelogPath, updatedChangelog);
} }
if (pkg.version.includes('-')) {
console.warn('Skipping changelog update for pre-release version');
return;
}
updateChangeLog(); updateChangeLog();
...@@ -5,12 +5,22 @@ ...@@ -5,12 +5,22 @@
# #
# This script is needed because a new release of a package is not always # This script is needed because a new release of a package is not always
# immediately available after "npm publish" returns. # immediately available after "npm publish" returns.
#
# Usage: wait-for-npm-release.sh [<dist-tag>]
#
# <dist-tag> defaults to "latest".
if [ -z "$1" ]; then
dist_tag=latest
else
dist_tag=$1
fi
expected_version=$(node -p "require('./package.json').version") expected_version=$(node -p "require('./package.json').version")
while [ true ] while [ true ]
do do
released_version=$(npm show hypothesis dist-tags.latest) released_version=$(npm show hypothesis dist-tags.$dist_tag)
if [ $released_version = $expected_version ]; then if [ "$released_version" = "$expected_version" ]; then
break break
fi fi
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment