From b8416961205ac95331830ce78a07916f7b746cd8 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Thu, 8 Jun 2017 12:54:35 +0200 Subject: [PATCH 1/2] chore: deploy docs|code .angularjs.org to Firebase via Travis - code.angularjs.org and docs.angularjs.org are two separate Firebase projects - both are automatically deployed via Travis config - Travis is split up into 2 build stages: first, all tests are run, and if they pass, the deploy stage runs a single job with both deployments (actual deployment depends on the state of the commit) - docs. is deployed directly to Firebase hosting - code. is uploaded to Firebase Google Cloud Storage and uses Firebase hosting rewrites to acces the files - jenkins builds still push the code builds to the code.angularjs.org Github repository Closes #9674 --- .firebaserc | 5 + .gitignore | 1 + .travis.yml | 102 ++++++++++++------ Gruntfile.js | 14 ++- firebase.json | 27 +++++ readme.firebase.docs.md | 7 ++ .../.eslintrc.json | 5 + .../code.angularjs.org-firebase/.firebaserc | 5 + .../code.angularjs.org-firebase/firebase.json | 21 ++++ .../functions/index.js | 67 ++++++++++++ .../functions/package.json | 10 ++ .../public/favicon.ico | Bin 0 -> 1150 bytes .../public/googleb96cceae5888d79f.html | 1 + .../public/index.html | 10 ++ .../public/robots.txt | 5 + .../readme.firebase.code.md | 10 ++ .../code.angularjs.org-firebase/storage.rules | 7 ++ scripts/code.angularjs.org/publish.sh | 17 +-- scripts/travis/build.sh | 84 ++++++++------- 19 files changed, 311 insertions(+), 87 deletions(-) create mode 100644 .firebaserc create mode 100644 firebase.json create mode 100644 readme.firebase.docs.md create mode 100644 scripts/code.angularjs.org-firebase/.eslintrc.json create mode 100644 scripts/code.angularjs.org-firebase/.firebaserc create mode 100644 scripts/code.angularjs.org-firebase/firebase.json create mode 100644 scripts/code.angularjs.org-firebase/functions/index.js create mode 100644 scripts/code.angularjs.org-firebase/functions/package.json create mode 100644 scripts/code.angularjs.org-firebase/public/favicon.ico create mode 100644 scripts/code.angularjs.org-firebase/public/googleb96cceae5888d79f.html create mode 100644 scripts/code.angularjs.org-firebase/public/index.html create mode 100644 scripts/code.angularjs.org-firebase/public/robots.txt create mode 100644 scripts/code.angularjs.org-firebase/readme.firebase.code.md create mode 100644 scripts/code.angularjs.org-firebase/storage.rules diff --git a/.firebaserc b/.firebaserc new file mode 100644 index 000000000000..8691a8f11929 --- /dev/null +++ b/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "docs-angularjs-org-9p2" + } +} diff --git a/.gitignore b/.gitignore index e897180b89d1..d1af1b437976 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ performance/temp*.html *.swp angular.js.tmproj /node_modules/ +/scripts/code.angularjs.org-firebase/functions/node_modules/ bower_components/ angular.xcodeproj .idea diff --git a/.travis.yml b/.travis.yml index 478de09a5484..d193f3ca15f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,56 +1,88 @@ language: node_js sudo: false node_js: - - '6' - +- '6' cache: yarn: true directories: - - bower_components - + - bower_components branches: except: - - /^g3_.*$/ - + - "/^g3_.*$/" env: matrix: - - JOB=ci-checks - - JOB=unit BROWSER_PROVIDER=saucelabs - - JOB=docs-e2e BROWSER_PROVIDER=saucelabs - - JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs - - JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs + - JOB=ci-checks + - JOB=unit BROWSER_PROVIDER=saucelabs + - JOB=docs-e2e BROWSER_PROVIDER=saucelabs + - 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 - - 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 - -# 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= addons: apt: sources: - - ubuntu-toolchain-r-test + - ubuntu-toolchain-r-test packages: - - g++-4.8 - + - g++-4.8 before_script: - - du -sh ./node_modules ./bower_components/ || true - - ./scripts/travis/before_build.sh - +- du -sh ./node_modules ./bower_components/ || true +- "./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 + - https://webhooks.gitter.im/e/d2120f3f2bb39a4531b2 + - http://104.197.9.155:8484/hubot/travis/activity + on_success: always + on_failure: always + on_start: always +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) + diff --git a/Gruntfile.js b/Gruntfile.js index 5f602bed8fd7..8de52bca501f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -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 @@ -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?'); @@ -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 + '/' } }, @@ -418,7 +428,7 @@ module.exports = function(grunt) { 'write', 'docs', 'copy', - 'compress' + 'compress:build' ]); grunt.registerTask('ci-checks', [ 'ddescribe-iit', diff --git a/firebase.json b/firebase.json new file mode 100644 index 000000000000..6daa73e8c398 --- /dev/null +++ b/firebase.json @@ -0,0 +1,27 @@ +{ + "hosting": { + "public": "build/docs", + "ignore": [ + "/index-debug.html", + "/index-jquery.html" + ], + "redirects": [ + { + "source": "/", + "destination": "/index-production.html", + "type": 301 + }, + { + "source": "/index.html", + "destination": "/index-production.html", + "type": 301 + } + ], + "rewrites": [ + { + "source": "**/*!(.jpg|.jpeg|.gif|.png|.html|.js|.json|.css|.svg|.ttf|.woff|.woff2|.eot)", + "destination": "/index-production.html" + } + ] + } +} \ No newline at end of file diff --git a/readme.firebase.docs.md b/readme.firebase.docs.md new file mode 100644 index 000000000000..0d538fb7f2f9 --- /dev/null +++ b/readme.firebase.docs.md @@ -0,0 +1,7 @@ +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. diff --git a/scripts/code.angularjs.org-firebase/.eslintrc.json b/scripts/code.angularjs.org-firebase/.eslintrc.json new file mode 100644 index 000000000000..22abc7fb2b7a --- /dev/null +++ b/scripts/code.angularjs.org-firebase/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "env": { + "es6": true + } +} diff --git a/scripts/code.angularjs.org-firebase/.firebaserc b/scripts/code.angularjs.org-firebase/.firebaserc new file mode 100644 index 000000000000..5ae9ae1e0f91 --- /dev/null +++ b/scripts/code.angularjs.org-firebase/.firebaserc @@ -0,0 +1,5 @@ +{ + "projects": { + "default": "code-angularjs-org-338b8" + } +} diff --git a/scripts/code.angularjs.org-firebase/firebase.json b/scripts/code.angularjs.org-firebase/firebase.json new file mode 100644 index 000000000000..a4d299f9a105 --- /dev/null +++ b/scripts/code.angularjs.org-firebase/firebase.json @@ -0,0 +1,21 @@ +{ + "hosting": { + "public": "public", + "redirects": [ + { + "source": "/:version/docs", + "destination": "/:version/docs/index.html", + "type": 301 + } + ], + "rewrites": [ + { + "source": "/**", + "function": "sendStoredFile" + } + ] + }, + "storage": { + "rules": "storage.rules" + } +} diff --git a/scripts/code.angularjs.org-firebase/functions/index.js b/scripts/code.angularjs.org-firebase/functions/index.js new file mode 100644 index 000000000000..dfba2eee2f6d --- /dev/null +++ b/scripts/code.angularjs.org-firebase/functions/index.js @@ -0,0 +1,67 @@ +'use strict'; + +const functions = require('firebase-functions'); +const gcs = require('@google-cloud/storage')(); +const path = require('path'); + +const gcsBucket = 'code-angularjs-org-338b8.appspot.com'; +const LOCAL_TMP_FOLDER = '/tmp/'; + +function sendStoredFile(request, response) { + let filePathSegments = request.path.split('/').filter((segment) => { + return segment !== ''; + }); + + const version = filePathSegments[0]; + const isDocsPath = filePathSegments[1] === 'docs'; + const lastSegment = filePathSegments[filePathSegments.length - 1]; + let downloadPath; + let fileName; + + if (isDocsPath && filePathSegments.length === 2) { + fileName = 'index.html'; + filePathSegments = [version, 'docs', fileName]; + } else { + fileName = lastSegment; + } + + downloadPath = path.join.apply(null, filePathSegments); + + const bucket = gcs.bucket(gcsBucket); + + downloadAndSend().catch(error => { + if (isDocsPath && error.code === 404) { + fileName = 'index.html'; + filePathSegments = [version, 'docs', fileName]; + downloadPath = path.join.apply(null, filePathSegments); + return downloadAndSend(); + } + + 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'; + } else { + message = 'File not found'; + } + } + + return response.status(error.code).send(message); + }); + + function downloadAndSend() { + return bucket.file(downloadPath).download({ + destination: `/tmp/${fileName}` + }).then(() => { + return response.status(200) + .set({ + 'Cache-Control': 'public, max-age=300, s-maxage=600' + }) + .sendFile(`${LOCAL_TMP_FOLDER}${fileName}`); + }); + } +} + +exports.sendStoredFile = functions.https.onRequest(sendStoredFile); diff --git a/scripts/code.angularjs.org-firebase/functions/package.json b/scripts/code.angularjs.org-firebase/functions/package.json new file mode 100644 index 000000000000..71a68bd6d34a --- /dev/null +++ b/scripts/code.angularjs.org-firebase/functions/package.json @@ -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 +} diff --git a/scripts/code.angularjs.org-firebase/public/favicon.ico b/scripts/code.angularjs.org-firebase/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..fe24a63a6ba4c4b4fb0e960abb60e51dc9097d43 GIT binary patch literal 1150 zcmZuxZAep57(QaqUkSemBP}6IGixM-R$2;?eQEiH)}M%sFz|;4MNX|WiYN&)b(!;H z6Y*nt*TibqTMgRG)HS!ek&a*=1h9&ehx^|5d7kq==bVdB5WYh~ z5Pn9Zl1&JOBZT5`;1tgM&*K3h{B8XO04Pv69FAiQqf%+L-x}R+cT}L7K)Hp5g#({H zs)ujg7~xW4RgiVK6Q0-0+&Z1^>C)0tWFQR5EiNv`j*gB=t1D>k=&rAj6sm=NVV@x` zw2hCPj4lwp82qEx>mRPHtc3aV7>%aNIw8HBkub*N2zEW5@azt2gMusxh+8R_*=)Y< z8=bRvJutLfX4G3b|p{YRzFR?!H&x@}p?E$;po?|kZ?qnve^}WB- z4mRsN9Ew)M*>nl7U3gmR!xE0m1>G<`JzX|FKGB*SHR01IKAcZw@!XtnuR;$E^#jn_ zB7;5QtJ(ygeY^|so_h9fSglM7om_(_976-Yz&vAx!9fa&&aBlY_#=rOpwVb3X$NB# zL~g_vWg3C__e!);o8Sd8VxX1ul+kDuzL7I*^-Y>1J_;gMx#WE_a1pONsV9-NO$>#n zBv32t<%SgRXIPfK>)nHR-y~wL8ac%ns>*5ZLYf+~Q@=oRY&%@ak;0? + + + + + AngularJS + + + + diff --git a/scripts/code.angularjs.org-firebase/public/robots.txt b/scripts/code.angularjs.org-firebase/public/robots.txt new file mode 100644 index 000000000000..480082428fa1 --- /dev/null +++ b/scripts/code.angularjs.org-firebase/public/robots.txt @@ -0,0 +1,5 @@ +User-agent: * + +Disallow: /*docs/ +Disallow: /*i18n/ +Disallow: /*.zip$ diff --git a/scripts/code.angularjs.org-firebase/readme.firebase.code.md b/scripts/code.angularjs.org-firebase/readme.firebase.code.md new file mode 100644 index 000000000000..55b9c78d0890 --- /dev/null +++ b/scripts/code.angularjs.org-firebase/readme.firebase.code.md @@ -0,0 +1,10 @@ +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. diff --git a/scripts/code.angularjs.org-firebase/storage.rules b/scripts/code.angularjs.org-firebase/storage.rules new file mode 100644 index 000000000000..d494542e9b28 --- /dev/null +++ b/scripts/code.angularjs.org-firebase/storage.rules @@ -0,0 +1,7 @@ +service firebase.storage { + match /b/{bucket}/o { + match /{allPaths=**} { + allow read, write: if request.auth!=null; + } + } +} diff --git a/scripts/code.angularjs.org/publish.sh b/scripts/code.angularjs.org/publish.sh index a9780a6de4a4..13420e725318 100755 --- a/scripts/code.angularjs.org/publish.sh +++ b/scripts/code.angularjs.org/publish.sh @@ -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 diff --git a/scripts/travis/build.sh b/scripts/travis/build.sh index bf9be1724550..bc71d1d836be 100755 --- a/scripts/travis/build.sh +++ b/scripts/travis/build.sh @@ -5,39 +5,51 @@ set -e export BROWSER_STACK_ACCESS_KEY=`echo $BROWSER_STACK_ACCESS_KEY | rev` export SAUCE_ACCESS_KEY=`echo $SAUCE_ACCESS_KEY | rev` -if [ "$JOB" == "ci-checks" ]; then - grunt ci-checks - if [[ $TRAVIS_PULL_REQUEST != 'false' ]]; then - # validate commit messages of all commits in the PR - # convert commit range to 2 dots, as commitplease uses `git log`. - # See https://github.com/travis-ci/travis-ci/issues/4596 for more info - echo "Validate commit messages in PR." - yarn run commitplease -- "${TRAVIS_COMMIT_RANGE/.../..}" - fi -elif [ "$JOB" == "unit" ]; then - if [ "$BROWSER_PROVIDER" == "browserstack" ]; then - BROWSERS="BS_Chrome,BS_Safari,BS_Firefox,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9" - else - BROWSERS="SL_Chrome,SL_Firefox,SL_Safari_8,SL_Safari_9,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS" - fi - - grunt test:promises-aplus - grunt test:unit --browsers="$BROWSERS" --reporters=spec - grunt tests:docs --browsers="$BROWSERS" --reporters=spec -elif [ "$JOB" == "docs-e2e" ]; then - grunt test:travis-protractor --specs="docs/app/e2e/**/*.scenario.js" -elif [ "$JOB" == "e2e" ]; then - if [[ $TEST_TARGET == jquery* ]]; then - export USE_JQUERY=1 - fi - - export TARGET_SPECS="build/docs/ptore2e/**/default_test.js" - if [[ "$TEST_TARGET" == jquery* ]]; then - TARGET_SPECS="build/docs/ptore2e/**/jquery_test.js" - fi - - export TARGET_SPECS="test/e2e/tests/**/*.js,$TARGET_SPECS" - grunt test:travis-protractor --specs="$TARGET_SPECS" -else - echo "Unknown job type. Please set JOB=ci-checks, JOB=unit or JOB=e2e-*." -fi +case "$JOB" in + "ci-checks") + grunt ci-checks + + if [[ $TRAVIS_PULL_REQUEST != 'false' ]]; then + # validate commit messages of all commits in the PR + # convert commit range to 2 dots, as commitplease uses `git log`. + # See https://github.com/travis-ci/travis-ci/issues/4596 for more info + echo "Validate commit messages in PR:" + yarn run commitplease -- "${TRAVIS_COMMIT_RANGE/.../..}" + fi + ;; + "unit") + if [ "$BROWSER_PROVIDER" == "browserstack" ]; then + BROWSERS="BS_Chrome,BS_Safari,BS_Firefox,BS_IE_9,BS_IE_10,BS_IE_11,BS_EDGE,BS_iOS_8,BS_iOS_9" + else + BROWSERS="SL_Chrome,SL_Firefox,SL_Safari_8,SL_Safari_9,SL_IE_9,SL_IE_10,SL_IE_11,SL_EDGE,SL_iOS" + fi + + grunt test:promises-aplus + grunt test:unit --browsers="$BROWSERS" --reporters=spec + grunt tests:docs --browsers="$BROWSERS" --reporters=spec + ;; + "docs-e2e") + grunt test:travis-protractor --specs="docs/app/e2e/**/*.scenario.js" + ;; + "e2e") + if [[ $TEST_TARGET == jquery* ]]; then + export USE_JQUERY=1 + fi + + export TARGET_SPECS="build/docs/ptore2e/**/default_test.js" + + if [[ "$TEST_TARGET" == jquery* ]]; then + TARGET_SPECS="build/docs/ptore2e/**/jquery_test.js" + fi + + export TARGET_SPECS="test/e2e/tests/**/*.js,$TARGET_SPECS" + grunt test:travis-protractor --specs="$TARGET_SPECS" + ;; + "deploy") + grunt package + grunt compress:firebaseCodeDeploy + ;; + *) + echo "Unknown job type. Please set JOB=ci-checks, JOB=unit, JOB=deploy or JOB=e2e-*." + ;; +esac From 7cda96a493bae442b26557ef639cd67754e81268 Mon Sep 17 00:00:00 2001 From: Martin Staffa Date: Wed, 12 Jul 2017 18:58:31 +0200 Subject: [PATCH 2/2] fixup! chore: deploy docs|code .angularjs.org to Firebase via Travis --- .gitignore | 3 +- .travis.yml | 64 +++++++++++-------- firebase.json | 13 ++-- readme.firebase.docs.md | 3 + .../functions/index.js | 34 ++++++---- .../readme.firebase.code.md | 2 + 6 files changed, 69 insertions(+), 50 deletions(-) diff --git a/.gitignore b/.gitignore index d1af1b437976..42c5e13b4421 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,7 @@ performance/temp*.html *~ *.swp angular.js.tmproj -/node_modules/ -/scripts/code.angularjs.org-firebase/functions/node_modules/ +node_modules/ bower_components/ angular.xcodeproj .idea diff --git a/.travis.yml b/.travis.yml index d193f3ca15f5..617083342a15 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,50 +1,60 @@ language: node_js sudo: false node_js: -- '6' + - '6' + cache: yarn: true directories: - - bower_components + - bower_components + branches: except: - - "/^g3_.*$/" + - "/^g3_.*$/" + env: matrix: - - JOB=ci-checks - - JOB=unit BROWSER_PROVIDER=saucelabs - - JOB=docs-e2e BROWSER_PROVIDER=saucelabs - - JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs - - JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs + - JOB=ci-checks + - JOB=unit BROWSER_PROVIDER=saucelabs + - JOB=docs-e2e BROWSER_PROVIDER=saucelabs + - JOB=e2e TEST_TARGET=jqlite BROWSER_PROVIDER=saucelabs + - JOB=e2e TEST_TARGET=jquery BROWSER_PROVIDER=saucelabs global: - - 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 + - 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= + addons: apt: sources: - - ubuntu-toolchain-r-test + - ubuntu-toolchain-r-test packages: - - g++-4.8 + - g++-4.8 + before_script: -- du -sh ./node_modules ./bower_components/ || true -- "./scripts/travis/before_build.sh" + - du -sh ./node_modules ./bower_components/ || true + - "./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 - on_success: always - on_failure: always - on_start: always + - 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 + jobs: include: - stage: deploy @@ -52,7 +62,7 @@ jobs: - JOB=deploy before_script: skip script: - - "./scripts/travis/build.sh" + - "./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() { diff --git a/firebase.json b/firebase.json index 6daa73e8c398..3427962f39bd 100644 --- a/firebase.json +++ b/firebase.json @@ -2,22 +2,19 @@ "hosting": { "public": "build/docs", "ignore": [ + "/index.html", "/index-debug.html", "/index-jquery.html" ], - "redirects": [ + "rewrites": [ { "source": "/", - "destination": "/index-production.html", - "type": 301 + "destination": "/index-production.html" }, { "source": "/index.html", - "destination": "/index-production.html", - "type": 301 - } - ], - "rewrites": [ + "destination": "/index-production.html" + }, { "source": "**/*!(.jpg|.jpeg|.gif|.png|.html|.js|.json|.css|.svg|.ttf|.woff|.woff2|.eot)", "destination": "/index-production.html" diff --git a/readme.firebase.docs.md b/readme.firebase.docs.md index 0d538fb7f2f9..d73e9a74f5d2 100644 --- a/readme.firebase.docs.md +++ b/readme.firebase.docs.md @@ -5,3 +5,6 @@ The docs are deployed to Google Firebase hosting via Travis deployment config, w firebase.json and .firebaserc in the repository root. See travis.yml for the complete deployment config. + +See /scripts/code.angularjs.org-firebase/readme.firebase.code.md for the firebase deployment to +code.angularjs.org \ No newline at end of file diff --git a/scripts/code.angularjs.org-firebase/functions/index.js b/scripts/code.angularjs.org-firebase/functions/index.js index dfba2eee2f6d..18fdd6c7a44a 100644 --- a/scripts/code.angularjs.org-firebase/functions/index.js +++ b/scripts/code.angularjs.org-firebase/functions/index.js @@ -4,18 +4,25 @@ const functions = require('firebase-functions'); const gcs = require('@google-cloud/storage')(); const path = require('path'); -const gcsBucket = 'code-angularjs-org-338b8.appspot.com'; +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]; - let downloadPath; + const bucket = gcs.bucket(gcsBucketId); + + let downloadSource; + let downloadDestination; let fileName; if (isDocsPath && filePathSegments.length === 2) { @@ -25,16 +32,17 @@ function sendStoredFile(request, response) { fileName = lastSegment; } - downloadPath = path.join.apply(null, filePathSegments); + downloadSource = path.join.apply(null, filePathSegments); + downloadDestination = `${LOCAL_TMP_FOLDER}${fileName}`; - const bucket = gcs.bucket(gcsBucket); - - downloadAndSend().catch(error => { + downloadAndSend(downloadSource, downloadDestination).catch(error => { if (isDocsPath && error.code === 404) { fileName = 'index.html'; filePathSegments = [version, 'docs', fileName]; - downloadPath = path.join.apply(null, filePathSegments); - return downloadAndSend(); + downloadSource = path.join.apply(null, filePathSegments); + downloadDestination = `${LOCAL_TMP_FOLDER}${fileName}`; + + return downloadAndSend(downloadSource, downloadDestination); } return Promise.reject(error); @@ -51,15 +59,15 @@ function sendStoredFile(request, response) { return response.status(error.code).send(message); }); - function downloadAndSend() { - return bucket.file(downloadPath).download({ - destination: `/tmp/${fileName}` + function downloadAndSend(downloadSource, downloadDestination) { + return bucket.file(downloadSource).download({ + destination: downloadDestination }).then(() => { return response.status(200) .set({ - 'Cache-Control': 'public, max-age=300, s-maxage=600' + 'Cache-Control': `public, max-age=${BROWSER_CACHE_DURATION}, s-maxage=${CDN_CACHE_DURATION}` }) - .sendFile(`${LOCAL_TMP_FOLDER}${fileName}`); + .sendFile(downloadDestination); }); } } diff --git a/scripts/code.angularjs.org-firebase/readme.firebase.code.md b/scripts/code.angularjs.org-firebase/readme.firebase.code.md index 55b9c78d0890..58a5d25835d4 100644 --- a/scripts/code.angularjs.org-firebase/readme.firebase.code.md +++ b/scripts/code.angularjs.org-firebase/readme.firebase.code.md @@ -8,3 +8,5 @@ in functions/index.js that serves the docs from the Firebase Google Cloud Storag The deployment to the Google Cloud Storage bucket happens automatically via Travis. See the travis.yml file in the repository root. + +See /readme.firebase.docs.md for the firebase deployment to docs.angularjs.org \ No newline at end of file