-
Notifications
You must be signed in to change notification settings - Fork 27.4k
chore: deploy docs|code .angularjs.org to Firebase via Travis #16093
Conversation
}).then(() => { | ||
return response.status(200) | ||
.set({ | ||
'Cache-Control': 'public, max-age=300, s-maxage=600' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can tweak the cache values later: s-maxage is the value for the Firebase CDN, max-age for the browser
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can move these values to configuration constants somewhere?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking great @Narretz.
I have a left a few minor comments.
@IgorMinar - shall we generate secrets from a central account?
.gitignore
Outdated
@@ -10,6 +10,7 @@ performance/temp*.html | |||
*.swp | |||
angular.js.tmproj | |||
/node_modules/ | |||
/scripts/code.angularjs.org-firebase/functions/node_modules/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a bit hard coded.
If we just change the previous line to node_modules
, without the slashes I think we would also capture this additional folder further down. Are there some node_modules
folders in the site that we do want to capture?
An alternative would be to put a .gitignore
at the /scripts/code.angularjs.org-firebase/functions
folder level.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's a node_modules that is checked in. Will change
.travis.yml
Outdated
on_start: always | ||
jobs: | ||
include: | ||
- stage: deploy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you removed all the indentation from lists in all the previous lines but then from here on down the indentation is there. I think we should be consistent. My understanding is that it is conventional to have indentation. Was there a reason for removing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This happened when I used the command line travis interface to add a value to the travis.yml. I will restore the original indentation
firebase.json
Outdated
{ | ||
"source": "/", | ||
"destination": "/index-production.html", | ||
"type": 301 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So you could not get the rewrites to work for /
and /index.html
?
This doesn't feel that nice, since people going to /
will actually see the browser url change to /index-production.html
.
If we can't get rewriting to work, perhaps we should just rename the file before deploying to docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the rewrites don't work because static matches take precedence over them. But what works (thanks to @gkalpak for the idea) is not to upload index.html, and rewrite /
and index.html
to index-production.html
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. |
There was a problem hiding this comment.
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.
{ | ||
"source": "/:version/docs", | ||
"destination": "/:version/docs/index.html", | ||
"type": 301 |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 🤔
}).then(() => { | ||
return response.status(200) | ||
.set({ | ||
'Cache-Control': 'public, max-age=300, s-maxage=600' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we can move these values to configuration constants somewhere?
function sendStoredFile(request, response) { | ||
let filePathSegments = request.path.split('/').filter((segment) => { | ||
return segment !== ''; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is to split off //
from the path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would path.normalize()
also work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used to remove empty entries from the array coming from leading or trailing slashes in the path
return response.status(error.code).send(message); | ||
}); | ||
|
||
function downloadAndSend() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you pass the downloadPath
and fileName
to this function as parameters?
Accessing them from the closure makes the code harder to follow, since we have to check what might have changed these value throughout the code.
let message = 'General error'; | ||
if (error.code === 404) { | ||
if (fileName.split('.').length === 1) { | ||
message = 'Directory listing is not supported'; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
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
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. |
There was a problem hiding this comment.
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.
firebase.json
Outdated
"public": "build/docs", | ||
"ignore": [ | ||
"/index-debug.html", | ||
"/index-jquery.html" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we ignore /index.html
as well? What is it used for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing, but Firebase logs a warning if there's no index.html. Not a problem, though.
Actually it works better without the index.html, see below.
function sendStoredFile(request, response) { | ||
let filePathSegments = request.path.split('/').filter((segment) => { | ||
return segment !== ''; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would path.normalize()
also work?
let message = 'General error'; | ||
if (error.code === 404) { | ||
if (fileName.split('.').length === 1) { | ||
message = 'Directory listing is not supported'; |
There was a problem hiding this comment.
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)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've addressed all your comments - only the redirect in code seems unfixable and directory listing / gcs static hosting can be handled later
.gitignore
Outdated
@@ -10,6 +10,7 @@ performance/temp*.html | |||
*.swp | |||
angular.js.tmproj | |||
/node_modules/ | |||
/scripts/code.angularjs.org-firebase/functions/node_modules/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there's a node_modules that is checked in. Will change
.travis.yml
Outdated
on_start: always | ||
jobs: | ||
include: | ||
- stage: deploy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This happened when I used the command line travis interface to add a value to the travis.yml. I will restore the original indentation
firebase.json
Outdated
"public": "build/docs", | ||
"ignore": [ | ||
"/index-debug.html", | ||
"/index-jquery.html" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing, but Firebase logs a warning if there's no index.html. Not a problem, though.
Actually it works better without the index.html, see below.
firebase.json
Outdated
{ | ||
"source": "/", | ||
"destination": "/index-production.html", | ||
"type": 301 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the rewrites don't work because static matches take precedence over them. But what works (thanks to @gkalpak for the idea) is not to upload index.html, and rewrite /
and index.html
to index-production.html
function sendStoredFile(request, response) { | ||
let filePathSegments = request.path.split('/').filter((segment) => { | ||
return segment !== ''; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used to remove empty entries from the array coming from leading or trailing slashes in the path
let message = 'General error'; | ||
if (error.code === 404) { | ||
if (fileName.split('.').length === 1) { | ||
message = 'Directory listing is not supported'; |
There was a problem hiding this comment.
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
{ | ||
"source": "/:version/docs", | ||
"destination": "/:version/docs/index.html", | ||
"type": 301 |
There was a problem hiding this comment.
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 🤔
const gcs = require('@google-cloud/storage')(); | ||
const path = require('path'); | ||
|
||
const gcsBucket = 'code-angularjs-org-338b8.appspot.com'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an environment variable that we can use: process.env.GCLOUD_PROJECT
- 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 angular#9674
He suggests that we go with the secrets that we have for now as we don't have a general solution to this yet. |
- 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 angular#9674 Closes angular#16093
- 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 angular#9674 Closes angular#16093
- 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 Closes #16093
stage runs a single job with both deployments (actual deployment depends on the state of the commit)
files
Further notes: