Skip to content

Commit be971cd

Browse files
authored
Merge branch 'GoogleChrome:main' into main
2 parents 11159cb + 20480b6 commit be971cd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+2390
-437
lines changed

.cloudbuild/cleanup.yaml

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
steps:
2-
- name: 'gcr.io/cloud-builders/gcloud'
3-
entrypoint: 'bash'
4-
args: ['-c', './.cloudbuild/cleanup.sh']
2+
- name: 'gcr.io/cloud-builders/gcloud'
3+
entrypoint: 'bash'
4+
args: ['-c', './.cloudbuild/cleanup.sh']

.cloudbuild/deploy.yaml

+29-23
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,36 @@
11
timeout: 2700s # set build timeout to 45 mins
22
steps:
3-
- name: node
4-
entrypoint: npm
5-
args: ['ci']
6-
- name: node
7-
entrypoint: npm
8-
args: ['run', 'cloud-secrets']
9-
env:
10-
- 'PROJECT_ID=$PROJECT_ID'
11-
- name: node
12-
entrypoint: npm
13-
args: ['run', 'production']
14-
- name: node
15-
entrypoint: npm
16-
args: ['run', 'algolia']
17-
- name: 'gcr.io/cloud-builders/gcloud'
18-
entrypoint: 'bash'
19-
args:
20-
- '-c'
21-
- |
22-
# This snippet lets us pass additional args via the Cloud Build console
23-
# in the _EXTRA_GCLOUD_ARGS var.
24-
# nb. We don't have to specify --project; it's part of the environment.
25-
gcloud app deploy ${_EXTRA_GCLOUD_ARGS}
3+
- name: node
4+
entrypoint: npm
5+
args: ['ci']
6+
7+
- name: node
8+
entrypoint: npm
9+
args: ['run', 'cloud-secrets']
10+
11+
- name: node
12+
entrypoint: npm
13+
args: ['run', 'production']
14+
15+
- name: node
16+
entrypoint: npm
17+
args: ['run', 'algolia']
18+
19+
- name: 'gcr.io/cloud-builders/gcloud'
20+
entrypoint: 'bash'
21+
args:
22+
- '-c'
23+
- |
24+
# This snippet lets us pass additional args via the Cloud Build console
25+
# in the _EXTRA_GCLOUD_ARGS var.
26+
# nb. We don't have to specify --project; it's part of the environment.
27+
gcloud app deploy ${_EXTRA_GCLOUD_ARGS}
28+
2629
substitutions:
2730
_EXTRA_GCLOUD_ARGS: # default empty
2831

2932
options:
3033
machineType: 'E2_HIGHCPU_8' # yolo
34+
env:
35+
- 'NODE_OPTIONS=--unhandled-rejections=strict'
36+
- 'PROJECT_ID=$PROJECT_ID'

.cloudbuild/external.yaml

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This builds external data, and if the site passes a basic build, writes the data to
2+
# Cloud Storage.
3+
4+
timeout: 900s # set build timeout to 15 mins
5+
6+
steps:
7+
- name: node:14
8+
id: 'Install dependencies'
9+
entrypoint: npm
10+
args: ['ci']
11+
12+
- name: node:14
13+
id: 'Configure secrets'
14+
entrypoint: npm
15+
args: ['run', 'cloud-secrets']
16+
17+
- name: node:14
18+
id: 'Build external data'
19+
entrypoint: npm
20+
args: ['run', 'build-external']
21+
env:
22+
- 'NODE_ENV=production'
23+
24+
- name: node:14
25+
id: 'Create .eleventyignore file'
26+
entrypoint: npm
27+
args: ['run', 'ignore']
28+
env:
29+
# TODO: We should try to remove more stuff here, because it's supposed to
30+
# be a fast build to sanity-check output.
31+
# It needs to include extensions and API generation.
32+
- 'ELEVENTY_IGNORE_NACL=true'
33+
34+
- name: node:14
35+
id: 'Build eleventy in dev mode to confirm'
36+
entrypoint: npm
37+
args: ['run', 'eleventy']
38+
# This does NOT set `NODE_ENV=production`, as we don't need the full build.
39+
40+
- name: 'gcr.io/cloud-builders/gcloud'
41+
id: 'Synchronize content to external-dcc-data bucket'
42+
entrypoint: bash
43+
args:
44+
- '-c'
45+
- |
46+
gsutil rsync external/data/ gs://external-dcc-data
47+
48+
options:
49+
env:
50+
- 'PROJECT_ID=$PROJECT_ID'
51+
- 'NODE_OPTIONS=--unhandled-rejections=strict'

.eleventy.js

+3
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,9 @@ module.exports = eleventyConfig => {
6161
// to use it for its build.
6262
eleventyConfig.setUseGitIgnore(false);
6363

64+
// Watch our external data in case it is synchronized or rebuilt.
65+
eleventyConfig.addWatchTarget('./external/data/');
66+
6467
// Merge eleventy's data cascade. This means directory data files will
6568
// cascade down to any child directories.
6669
eleventyConfig.setDataDeepMerge(true);

.github/workflows/check.yml

+11-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ jobs:
77
lint_and_test:
88
name: Lint, test and build
99
runs-on: ubuntu-latest
10+
env:
11+
# Increase RAM limit, and make uncaught exceptions crash (default in 16+).
12+
NODE_OPTIONS: --max_old_space_size=4096 --unhandled-rejections=strict
1013
steps:
1114
- name: Checkout
1215
uses: actions/[email protected]
@@ -46,6 +49,8 @@ jobs:
4649
- '**/*.scss'
4750
njk:
4851
- '**/*.njk'
52+
_external:
53+
- 'external/**/*'
4954
5055
# Use the filter to check if files with a specific file type were changed
5156
# in the PR. If they were, run the relevant linters. Otherwise, skip.
@@ -66,9 +71,13 @@ jobs:
6671
if: ${{ steps.filter.outputs.scss == 'true' }}
6772
run: npm run lint:scss
6873

74+
- name: Build External
75+
if: ${{ steps.filter.outputs._external == 'true' }}
76+
run: npm run build-external
77+
6978
- name: Build Eleventy
70-
if: ${{ steps.filter.outputs.md == 'true' || steps.filter.outputs.js == 'true' || steps.filter.outputs.yml == 'true' || steps.filter.outputs.njk == 'true'}}
71-
run: npm run ignore && npm run eleventy
79+
if: ${{ steps.filter.outputs.md == 'true' || steps.filter.outputs.js == 'true' || steps.filter.outputs.yml == 'true' || steps.filter.outputs.njk == 'true' }}
80+
run: npm run ignore && npm run maybe-sync-external && npm run eleventy
7281

7382
# Only run tests if the PR touches behavior related files.
7483
- name: Test

.github/workflows/lighthouse-ci.yml

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ jobs:
1515
lhci:
1616
if: ${{ github.repository == 'GoogleChrome/developer.chrome.com' }}
1717
runs-on: ubuntu-latest
18+
env:
19+
# Increase RAM limit, and make uncaught exceptions crash (default in 16+).
20+
NODE_OPTIONS: --max_old_space_size=4096 --unhandled-rejections=strict
1821
steps:
1922
- name: Checkout
2023
uses: actions/[email protected]

.github/workflows/percy.yml

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ jobs:
2323
percy:
2424
if: ${{ github.repository == 'GoogleChrome/developer.chrome.com' }}
2525
runs-on: ubuntu-latest
26+
env:
27+
# Increase RAM limit, and make uncaught exceptions crash (default in 16+).
28+
NODE_OPTIONS: --max_old_space_size=4096 --unhandled-rejections=strict
2629
steps:
2730
- name: Checkout
2831
uses: actions/[email protected]

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ dist
2525
# Eleventy
2626
# We generate our own .eleventyignore file dynamically during builds
2727
.eleventyignore
28+
29+
# External source files
30+
external/data/
31+
external/local-build-flag

external/README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
This folder contains the system that deals with external data for developer.chrome.com, that is, data that regularly changes yet is required to publish the site.
2+
3+
- the "data/" folder is used as a working dir (and isn't checked in)
4+
5+
- all scripts inside "build/" are run when `npm run build-external` is run, and a local flag is set
6+
7+
- otherwise, run `npm run sync-external` to retrieve the last known good files stored in Cloud Storage
8+
9+
- running `npm run dev` will automatically pull external data
10+
11+
## Changes
12+
13+
If you make changes to the build script(s), you can manually kick off a Cloud Build task to confirm that the output builds and to write it to storage for other users.
14+
15+
```bash
16+
$ gcloud builds submit --config .cloudbuild/external.yaml .
17+
```
18+
19+
You can confirm the contents of the bucket by:
20+
21+
```bash
22+
$ gsutil ls -l gs://external-dcc-data
23+
```

external/build-external.js

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/**
2+
* @fileoverview Builds all external sources. This clears the data/ folder here
3+
* and runs all scripts in build/, which can write new files there.
4+
*
5+
* This is intended for use by Cloud Build, or by site devs doing local work.
6+
*/
7+
8+
const fs = require('fs');
9+
const path = require('path');
10+
const glob = require('glob');
11+
const childProcess = require('child_process');
12+
const crypto = require('crypto');
13+
const syncTestdata = require('./lib/sync-testdata');
14+
15+
async function run() {
16+
let errors = 0;
17+
18+
const scripts = glob.sync('build/*.js', {cwd: __dirname});
19+
scripts.sort(); // run in alphabetical order
20+
21+
const projectRoot = path.join(__dirname, '..');
22+
23+
const dataTarget = path.join(__dirname, 'data');
24+
fs.rmSync(dataTarget, {recursive: true, force: true});
25+
fs.mkdirSync(dataTarget, {recursive: true});
26+
27+
// If this is a CI build, we start with everything found in "fallback/". It won't win, but it
28+
// will be used in cases where credentials and such aren't available.
29+
if (process.env.CI) {
30+
const all = await syncTestdata();
31+
console.info('! Using fallback before build in CI, copied:', all);
32+
}
33+
34+
/** @type {childProcess.CommonExecOptions} */
35+
const options = {cwd: projectRoot, stdio: 'inherit'};
36+
37+
for (const script of scripts) {
38+
const r = path.join(__dirname, script);
39+
console.info('> Running', r);
40+
try {
41+
childProcess.execFileSync('node', [r], options);
42+
} catch (e) {
43+
// We don't log the error here, as we're already getting STDERR piped above.
44+
console.warn(`! Failed to execute "${script}" (${e.status})`);
45+
++errors;
46+
}
47+
}
48+
49+
// Determine the hash for everything in data/.
50+
const hash = crypto.createHash('sha256');
51+
const allFiles = glob.sync('data/**/*', {cwd: __dirname});
52+
if (!allFiles.length) {
53+
throw new Error('no files generated, cowardly refusing to hash');
54+
}
55+
56+
// Sort allFiles, in case glob.sync is inconsistent.
57+
allFiles.sort();
58+
59+
for (const f of allFiles) {
60+
const p = path.join(__dirname, f);
61+
const bytes = fs.readFileSync(p);
62+
hash.update(bytes);
63+
}
64+
const digest = hash.digest('hex');
65+
console.info(
66+
`@ Generated digest=${digest} for ${allFiles.length} files:`,
67+
allFiles
68+
);
69+
fs.writeFileSync(path.join(__dirname, 'data/.hash'), digest);
70+
71+
// If there were any errors, return with a non-zero status code anyway.
72+
if (errors) {
73+
// eslint-disable-next-line no-process-exit
74+
process.exit(1);
75+
}
76+
77+
// Mark this local environment as being build-only, so it won't automatically sync.
78+
const payload =
79+
'// This file blocks synchronizing local data, because you ran `npm run build-external`.\n' +
80+
'// Delete it to bring back automatic sync when you run `npm run dev`.';
81+
fs.writeFileSync(path.join(__dirname, 'local-build-flag'), payload);
82+
}
83+
84+
run();

external/build/chrome-release.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/**
2+
* @fileoverview Fetches Chrome release data and writes to storage.
3+
*/
4+
5+
const buildVersionInformation = require('./lib/chrome-release.js');
6+
const fs = require('fs');
7+
const path = require('path');
8+
9+
async function run() {
10+
const versionInformation = await buildVersionInformation();
11+
12+
const targetFile = path.join(__dirname, '../data/chrome-release.json');
13+
fs.writeFileSync(targetFile, JSON.stringify(versionInformation));
14+
}
15+
16+
run();

0 commit comments

Comments
 (0)