Skip to content

Commit

Permalink
New Publish Path (#231)
Browse files Browse the repository at this point in the history
  • Loading branch information
bkendall authored Mar 19, 2020
1 parent 2940a4b commit 6873662
Show file tree
Hide file tree
Showing 10 changed files with 322 additions and 2 deletions.
7 changes: 5 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/firebase/firebase-functions.git"
"url": "https://github.com/firebase/firebase-functions.git"
},
"license": "MIT",
"author": "Firebase Team",
Expand All @@ -23,10 +23,13 @@
],
"main": "lib/index.js",
"types": "lib/index.d.ts",
"publishConfig": {
"registry": "https://wombat-dressing-room.appspot.com"
},
"scripts": {
"apidocs": "node docgen/generate-docs.js",
"build:pack": "rm -rf lib && npm install && tsc -p tsconfig.release.json && npm pack",
"build:release": "npm install --production && npm install typescript firebase-admin && tsc -p tsconfig.release.json",
"build:release": "npm install --production && npm install --no-save typescript firebase-admin && tsc -p tsconfig.release.json",
"build": "tsc -p tsconfig.release.json",
"format": "prettier --check '**/*.{json,md,ts,yml,yaml}'",
"format:fix": "prettier --write '**/*.{json,md,ts,yml,yaml}'",
Expand Down
12 changes: 12 additions & 0 deletions scripts/publish-container/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM node:8

# Install dependencies
RUN apt-get update && \
apt-get install -y curl git jq

# Install npm at latest.
RUN npm install --global npm@latest

# Install hub
RUN curl -fsSL --output hub.tgz https://github.com/github/hub/releases/download/v2.13.0/hub-linux-amd64-2.13.0.tgz
RUN tar --strip-components=2 -C /usr/bin -xf hub.tgz hub-linux-amd64-2.13.0/bin/hub
4 changes: 4 additions & 0 deletions scripts/publish-container/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/package-builder', '.']
images: ['gcr.io/$PROJECT_ID/package-builder']
135 changes: 135 additions & 0 deletions scripts/publish.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/bin/bash
set -e

printusage() {
echo "publish.sh <version>"
echo "REPOSITORY_ORG and REPOSITORY_NAME should be set in the environment."
echo "e.g. REPOSITORY_ORG=user, REPOSITORY_NAME=repo"
echo ""
echo "Arguments:"
echo " version: 'patch', 'minor', or 'major'."
}

VERSION=$1
if [[ $VERSION == "" ]]; then
printusage
exit 1
elif [[ ! ($VERSION == "patch" || $VERSION == "minor" || $VERSION == "major") ]]; then
printusage
exit 1
fi

if [[ $REPOSITORY_ORG == "" ]]; then
printusage
exit 1
fi
if [[ $REPOSITORY_NAME == "" ]]; then
printusage
exit 1
fi

WDIR=$(pwd)

echo "Checking for commands..."
trap "echo 'Missing hub.'; exit 1" ERR
which hub &> /dev/null
trap - ERR

trap "echo 'Missing node.'; exit 1" ERR
which node &> /dev/null
trap - ERR

trap "echo 'Missing jq.'; exit 1" ERR
which jq &> /dev/null
trap - ERR
echo "Checked for commands."

echo "Checking for Twitter credentials..."
trap "echo 'Missing Twitter credentials.'; exit 1" ERR
test -f "${WDIR}/scripts/twitter.json"
trap - ERR
echo "Checked for Twitter credentials..."

echo "Checking for logged-in npm user..."
trap "echo 'Please login to npm using \`npm login --registry https://wombat-dressing-room.appspot.com\`'; exit 1" ERR
npm whoami --registry https://wombat-dressing-room.appspot.com
trap - ERR
echo "Checked for logged-in npm user."

echo "Moving to temporary directory.."
TEMPDIR=$(mktemp -d)
echo "[DEBUG] ${TEMPDIR}"
cd "${TEMPDIR}"
echo "Moved to temporary directory."

echo "Cloning repository..."
git clone "[email protected]:${REPOSITORY_ORG}/${REPOSITORY_NAME}.git"
cd "${REPOSITORY_NAME}"
echo "Cloned repository."

echo "Making sure there is a changelog..."
if [ ! -s CHANGELOG.md ]; then
echo "CHANGELOG.md is empty. aborting."
exit 1
fi
echo "Made sure there is a changelog."

echo "Running npm install..."
npm install
echo "Ran npm install."

echo "Running tests..."
npm test
echo "Ran tests."

echo "Running publish build..."
npm run build:release
echo "Ran publish build."

echo "Making a $VERSION version..."
npm version $VERSION
NEW_VERSION=$(jq -r ".version" package.json)
echo "Made a $VERSION version."

echo "Making the release notes..."
RELEASE_NOTES_FILE=$(mktemp)
echo "[DEBUG] ${RELEASE_NOTES_FILE}"
echo "v${NEW_VERSION}" >> "${RELEASE_NOTES_FILE}"
echo "" >> "${RELEASE_NOTES_FILE}"
cat CHANGELOG.md >> "${RELEASE_NOTES_FILE}"
echo "Made the release notes."

echo "Publishing to npm..."
if [[ $DRY_RUN == "" ]]; then
npm publish
else
echo "DRY RUN: running publish with --dry-run"
npm publish --dry-run
fi
echo "Published to npm."

if [[ $DRY_RUN != "" ]]; then
echo "All other commands are mutations, and we are doing a dry run."
echo "Terminating."
exit
fi

echo "Cleaning up release notes..."
rm CHANGELOG.md
touch CHANGELOG.md
git commit -m "[firebase-release] Removed change log and reset repo after ${NEW_VERSION} release" CHANGELOG.md
echo "Cleaned up release notes."

echo "Pushing to GitHub..."
git push origin master --tags
echo "Pushed to GitHub."

echo "Publishing release notes..."
hub release create --file "${RELEASE_NOTES_FILE}" "v${NEW_VERSION}"
echo "Published release notes."

echo "Making the tweet..."
npm install --no-save [email protected]
cp -v "${WDIR}/scripts/twitter.json" "${TEMPDIR}/${REPOSITORY_NAME}/scripts/"
node ./scripts/tweet.js ${NEW_VERSION}
echo "Made the tweet."
114 changes: 114 additions & 0 deletions scripts/publish/cloudbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
steps:
# Decrypt the SSH key.
- name: 'gcr.io/cloud-builders/gcloud'
args:
[
'kms',
'decrypt',
'--ciphertext-file=deploy_key.enc',
'--plaintext-file=/root/.ssh/id_rsa',
'--location=global',
'--keyring=${_KEY_RING}',
'--key=${_KEY_NAME}',
]

# Decrypt the Twitter credentials.
- name: 'gcr.io/cloud-builders/gcloud'
args:
[
'kms',
'decrypt',
'--ciphertext-file=twitter.json.enc',
'--plaintext-file=twitter.json',
'--location=global',
'--keyring=${_KEY_RING}',
'--key=${_KEY_NAME}',
]

# Decrypt the npm credentials.
- name: 'gcr.io/cloud-builders/gcloud'
args:
[
'kms',
'decrypt',
'--ciphertext-file=npmrc.enc',
'--plaintext-file=npmrc',
'--location=global',
'--keyring=${_KEY_RING}',
'--key=${_KEY_NAME}',
]

# Decrypt the hub (GitHub) credentials.
- name: 'gcr.io/cloud-builders/gcloud'
args:
[
'kms',
'decrypt',
'--ciphertext-file=hub.enc',
'--plaintext-file=hub',
'--location=global',
'--keyring=${_KEY_RING}',
'--key=${_KEY_NAME}',
]

# Set up git with key and domain.
- name: 'gcr.io/cloud-builders/git'
entrypoint: 'bash'
args:
- '-c'
- |
chmod 600 /root/.ssh/id_rsa
cat <<EOF >/root/.ssh/config
Hostname github.com
IdentityFile /root/.ssh/id_rsa
EOF
ssh-keyscan github.com >> /root/.ssh/known_hosts
# Clone the repository.
- name: 'gcr.io/cloud-builders/git'
args: ['clone', '[email protected]:${_REPOSITORY_ORG}/${_REPOSITORY_NAME}']

# Set up the Git configuration.
- name: 'gcr.io/cloud-builders/git'
dir: '${_REPOSITORY_NAME}'
args: ['config', '--global', 'user.email', '[email protected]']
- name: 'gcr.io/cloud-builders/git'
dir: '${_REPOSITORY_NAME}'
args: ['config', '--global', 'user.name', 'Google Open Source Bot']

# Set up the Twitter credentials.
- name: 'gcr.io/$PROJECT_ID/package-builder'
entrypoint: 'cp'
args: ['-v', 'twitter.json', '${_REPOSITORY_NAME}/scripts/twitter.json']

# Set up the npm credentials.
- name: 'gcr.io/$PROJECT_ID/package-builder'
entrypoint: 'bash'
args: ['-c', 'cp -v npmrc ~/.npmrc']

# Set up the hub credentials for package-builder.
- name: 'gcr.io/$PROJECT_ID/package-builder'
entrypoint: 'bash'
args: ['-c', 'mkdir -vp ~/.config && cp -v hub ~/.config/hub']

# Publish the package.
- name: 'gcr.io/$PROJECT_ID/package-builder'
dir: '${_REPOSITORY_NAME}'
args: ['bash', './scripts/publish.sh', '${_VERSION}']
env:
- 'REPOSITORY_ORG=${_REPOSITORY_ORG}'
- 'REPOSITORY_NAME=${_REPOSITORY_NAME}'
- 'DRY_RUN=${_DRY_RUN}'

options:
volumes:
- name: 'ssh'
path: /root/.ssh

substitutions:
_VERSION: ''
_DRY_RUN: ''
_KEY_RING: 'npm-publish-keyring'
_KEY_NAME: 'publish'
_REPOSITORY_ORG: 'firebase'
_REPOSITORY_NAME: 'firebase-functions'
Binary file added scripts/publish/deploy_key.enc
Binary file not shown.
Binary file added scripts/publish/hub.enc
Binary file not shown.
Binary file added scripts/publish/npmrc.enc
Binary file not shown.
Binary file added scripts/publish/twitter.json.enc
Binary file not shown.
52 changes: 52 additions & 0 deletions scripts/tweet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
"use strict";

const fs = require("fs");
const Twitter = require("twitter");

function printUsage() {
console.error(
`
Usage: tweet.js <version>
Credentials must be stored in "twitter.json" in this directory.
Arguments:
- version: Version of module that was released. e.g. "1.2.3"
`
);
process.exit(1);
}

function getUrl(version) {
return `https://github.com/firebase/firebase-functions/releases/tag/v${version}`;
}

if (process.argv.length !== 3) {
console.error("Missing arguments.");
printUsage();
}

const version = process.argv.pop();
if (!version.match(/^\d+\.\d+\.\d+$/)) {
console.error(`Version "${version}" not a version number.`);
printUsage();
}

if (!fs.existsSync(`${__dirname}/twitter.json`)) {
console.error("Missing credentials.");
printUsage();
}
const creds = require("./twitter.json");

const client = new Twitter(creds);

client.post(
"statuses/update",
{ status: `v${version} of @Firebase SDK for Cloud Functions is available. Release notes: ${getUrl(version)}` },
(err) => {
if (err) {
console.error(err);
process.exit(1);
}
}
);

0 comments on commit 6873662

Please sign in to comment.