Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

chore: deploy docs|code .angularjs.org to Firebase via Travis #16093

Merged
merged 2 commits into from
Jul 13, 2017
Merged
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
5 changes: 5 additions & 0 deletions .firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "docs-angularjs-org-9p2"
}
}
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ performance/temp*.html
*~
*.swp
angular.js.tmproj
/node_modules/
node_modules/
bower_components/
angular.xcodeproj
.idea
Expand Down
66 changes: 54 additions & 12 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ cache:

branches:
except:
- /^g3_.*$/
- "/^g3_.*$/"

env:
matrix:
Expand All @@ -20,14 +20,15 @@ env:
- JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs
- JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs
global:
- CXX=g++-4.8 # node 4 likes the G++ v4.8 compiler
# node 4 likes the G++ v4.8 compiler
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
- CXX=g++-4.8
- SAUCE_USERNAME=angular-ci
- SAUCE_ACCESS_KEY=9b988f434ff8-fbca-8aa4-4ae3-35442987
- LOGS_DIR=/tmp/angular-build/logs
- BROWSER_PROVIDER_READY_FILE=/tmp/browsersprovider-tunnel-ready
- secure: oTBjhnOKhs0qDSKTf7fE4f6DYiNDPycvB7qfSF5QRIbJK/LK/J4UtFwetXuXj79HhUZG9qnoT+5e7lPaiaMlpsIKn9ann7ffqFWN1E8TMtpJF+AGigx3djYElwfgf5nEnFUFhwjFzvbfpZNnxVGgX5YbIZpe/WUbHkP4ffU0Wks=

# node 4 likes the G++ v4.8 compiler
# see https://docs.travis-ci.com/user/languages/javascript-with-nodejs#Node.js-v4-(or-io.js-v3)-compiler-requirements
addons:
apt:
sources:
Expand All @@ -37,20 +38,61 @@ addons:

before_script:
- du -sh ./node_modules ./bower_components/ || true
- ./scripts/travis/before_build.sh

- "./scripts/travis/before_build.sh"
script:
- ./scripts/travis/build.sh
- "./scripts/travis/build.sh"

after_script:
- ./scripts/travis/tear_down_browser_provider.sh
- ./scripts/travis/print_logs.sh
- "./scripts/travis/tear_down_browser_provider.sh"
- "./scripts/travis/print_logs.sh"

notifications:
webhooks:
urls:
- https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2
- http://104.197.9.155:8484/hubot/travis/activity #hubot-server
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: always # default: false
on_success: always # options: [always|never|change] default: always
on_failure: always # options: [always|never|change] default: always
on_start: always # default: false

jobs:
include:
- stage: deploy
env:
- JOB=deploy
before_script: skip
script:
- "./scripts/travis/build.sh"
# Work around the 10min Travis timeout so the code.angularjs firebase+gcs code deploy can complete
before_deploy: |
function keep_alive() {
while true; do
echo -en "\a"
sleep 5
done
}
keep_alive &
deploy:
- provider: firebase
skip_cleanup: true
token:
secure: $FIREBASE_TOKEN
on:
repo: angular/angular.js
all_branches: true
# deploy a new docs version when the commit is tagged on the "latest" npm version
condition: $TRAVIS_TAG != '' && $( jq ".distTag" "package.json" | tr -d "\"[:space:]" ) = latest
- provider: gcs
skip_cleanup: true
access_key_id: GOOGLDB7W2J3LFHICF3R
secret_access_key:
secure: tHIFdSq55qkyZf9zT/3+VkhUrTvOTMuswxXU3KyWaBrSieZqG0UnUDyNm+n3lSfX95zEl/+rJAWbfvhVSxZi13ndOtvRF+MdI1cvow2JynP0aDSiPffEvVrZOmihD6mt2SlMfhskr5FTduQ69kZG6DfLcve1PPDaIwnbOv3phb8=
bucket: code-angularjs-org-338b8.appspot.com
local-dir: upload
detect_encoding: true # detects gzip compression
on:
repo: angular/angular.js
all_branches: true
# upload the build when the commit is tagged or the branch is "master"
condition: $TRAVIS_TAG != '' || ($TRAVIS_PULL_REQUEST = false && $TRAVIS_BRANCH = master)

14 changes: 12 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ if (!process.env.TRAVIS && !process.env.JENKINS_HOME) {
}
}


module.exports = function(grunt) {

// this loads all the node_modules that start with `grunt-` as plugins
Expand All @@ -64,6 +63,8 @@ module.exports = function(grunt) {
NG_VERSION.cdn = versionInfo.cdnVersion;
var dist = 'angular-' + NG_VERSION.full;

var deployVersion = NG_VERSION.isSnapshot ? 'snapshot' : NG_VERSION.full;

if (versionInfo.cdnVersion == null) {
throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?\n' +
'Perhaps you want to set the NG1_BUILD_NO_REMOTE_VERSION_REQUESTS environment variable?');
Expand Down Expand Up @@ -324,6 +325,15 @@ module.exports = function(grunt) {
expand: true,
dot: true,
dest: dist + '/'
},
firebaseCodeDeploy: {
options: {
mode: 'gzip'
},
src: ['**'],
cwd: 'build',
expand: true,
dest: 'upload/' + deployVersion + '/'
}
},

Expand Down Expand Up @@ -418,7 +428,7 @@ module.exports = function(grunt) {
'write',
'docs',
'copy',
'compress'
'compress:build'
]);
grunt.registerTask('ci-checks', [
'ddescribe-iit',
Expand Down
24 changes: 24 additions & 0 deletions firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"hosting": {
"public": "build/docs",
"ignore": [
"/index.html",
"/index-debug.html",
"/index-jquery.html"
],
"rewrites": [
{
"source": "/",
"destination": "/index-production.html"
},
{
"source": "/index.html",
"destination": "/index-production.html"
},
{
"source": "**/*!(.jpg|.jpeg|.gif|.png|.html|.js|.json|.css|.svg|.ttf|.woff|.woff2|.eot)",
"destination": "/index-production.html"
}
]
}
}
10 changes: 10 additions & 0 deletions readme.firebase.docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Firebase for docs.angularjs.org
===============================

The docs are deployed to Google Firebase hosting via Travis deployment config, which expects
firebase.json and .firebaserc in the repository root.

See travis.yml for the complete deployment config.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might be worth linking to scripts/code.angularjs.org-firebase/readme.firebase.code.md (the different code.angularjs.org deployment) in this file too.


See /scripts/code.angularjs.org-firebase/readme.firebase.code.md for the firebase deployment to
code.angularjs.org
5 changes: 5 additions & 0 deletions scripts/code.angularjs.org-firebase/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"env": {
"es6": true
}
}
5 changes: 5 additions & 0 deletions scripts/code.angularjs.org-firebase/.firebaserc
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"projects": {
"default": "code-angularjs-org-338b8"
}
}
21 changes: 21 additions & 0 deletions scripts/code.angularjs.org-firebase/firebase.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"hosting": {
"public": "public",
"redirects": [
{
"source": "/:version/docs",
"destination": "/:version/docs/index.html",
"type": 301
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am less concerned about this redirect but it is a bit sad that Firebase doesn't support it via rewrites :-(.
Would a redirect from /:version/docs to /:version/docs/ work?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For some reason, redirect to /:version/docs/ results in an infinite redirect loop in the browser 🤔

}
],
"rewrites": [
{
"source": "/**",
"function": "sendStoredFile"
}
]
},
"storage": {
"rules": "storage.rules"
}
}
75 changes: 75 additions & 0 deletions scripts/code.angularjs.org-firebase/functions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
'use strict';

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const path = require('path');

const gcsBucketId = `${process.env.GCLOUD_PROJECT}.appspot.com`;
const LOCAL_TMP_FOLDER = '/tmp/';

const BROWSER_CACHE_DURATION = 300;
const CDN_CACHE_DURATION = 600;

function sendStoredFile(request, response) {
let filePathSegments = request.path.split('/').filter((segment) => {
// Remove empty leading or trailing path parts
return segment !== '';
});

const version = filePathSegments[0];
const isDocsPath = filePathSegments[1] === 'docs';
const lastSegment = filePathSegments[filePathSegments.length - 1];
const bucket = gcs.bucket(gcsBucketId);

let downloadSource;
let downloadDestination;
let fileName;

if (isDocsPath && filePathSegments.length === 2) {
fileName = 'index.html';
filePathSegments = [version, 'docs', fileName];
} else {
fileName = lastSegment;
}

downloadSource = path.join.apply(null, filePathSegments);
downloadDestination = `${LOCAL_TMP_FOLDER}${fileName}`;

downloadAndSend(downloadSource, downloadDestination).catch(error => {
if (isDocsPath && error.code === 404) {
fileName = 'index.html';
filePathSegments = [version, 'docs', fileName];
downloadSource = path.join.apply(null, filePathSegments);
downloadDestination = `${LOCAL_TMP_FOLDER}${fileName}`;

return downloadAndSend(downloadSource, downloadDestination);
}

return Promise.reject(error);
}).catch(error => {
let message = 'General error';
if (error.code === 404) {
if (fileName.split('.').length === 1) {
message = 'Directory listing is not supported';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a shame. Could we look into supporting this in a future PR?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could we host directly from Google storage (something like this)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably. But I'm not convinced it is worth the effort to basically split the config in two. At the moment, direct access to gcs is only needed to upload the files, everything else goes through firebase

} else {
message = 'File not found';
}
}

return response.status(error.code).send(message);
});

function downloadAndSend(downloadSource, downloadDestination) {
return bucket.file(downloadSource).download({
destination: downloadDestination
}).then(() => {
return response.status(200)
.set({
'Cache-Control': `public, max-age=${BROWSER_CACHE_DURATION}, s-maxage=${CDN_CACHE_DURATION}`
})
.sendFile(downloadDestination);
});
}
}

exports.sendStoredFile = functions.https.onRequest(sendStoredFile);
10 changes: 10 additions & 0 deletions scripts/code.angularjs.org-firebase/functions/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "functions-firebase-code.angularjs.org",
"description": "Cloud Functions to serve files from gcs to code.angularjs.org",
"dependencies": {
"@google-cloud/storage": "^1.1.1",
"firebase-admin": "^4.2.1",
"firebase-functions": "^0.5.9"
},
"private": true
}
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
google-site-verification: googleb96cceae5888d79f.html
10 changes: 10 additions & 0 deletions scripts/code.angularjs.org-firebase/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>AngularJS</title>
</head>
<body>
</body>
</html>
5 changes: 5 additions & 0 deletions scripts/code.angularjs.org-firebase/public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
User-agent: *

Disallow: /*docs/
Disallow: /*i18n/
Disallow: /*.zip$
12 changes: 12 additions & 0 deletions scripts/code.angularjs.org-firebase/readme.firebase.code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Firebase for code.angularjs.org
===============================

This folder contains the Google Firebase scripts for the code.angularjs.org setup.

firebase.json contains the rewrite rules that route every subdirectory request to the cloud function
in functions/index.js that serves the docs from the Firebase Google Cloud Storage bucket.

The deployment to the Google Cloud Storage bucket happens automatically via Travis. See the travis.yml
file in the repository root.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could be worth a link to the other doc here, just in case people come across this file when they are looking for the other firebase configuration.


See /readme.firebase.docs.md for the firebase deployment to docs.angularjs.org
7 changes: 7 additions & 0 deletions scripts/code.angularjs.org-firebase/storage.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write: if request.auth!=null;
}
}
}
17 changes: 3 additions & 14 deletions scripts/code.angularjs.org/publish.sh
Original file line number Diff line number Diff line change
Expand Up @@ -59,23 +59,12 @@ function _update_code() {

echo "-- Pushing code.angularjs.org"
git push origin master

for backend in "$@" ; do
echo "-- Refreshing code.angularjs.org: backend=$backend"

# FIXME: We gave up publishing to code.angularjs.org because the GCE automatically removes firewall
# rules that allow access to port 8003.

# curl http://$backend:8003/gitFetchSite.php
done
}

function publish {
# The TXT record for backends.angularjs.org is a CSV of the IP addresses for
# the currently serving Compute Engine backends.
# code.angularjs.org is served out of port 8003 on these backends.
backends=("$(dig backends.angularjs.org +short TXT | python -c 'print raw_input()[1:-1].replace(",", "\n")')")
_update_code ${backends[@]}
# publish updates the code.angularjs.org Github repository
# the deployment to Firebase happens via Travis
_update_code
}

source $(dirname $0)/../utils.inc
Loading