Skip to content

Commit f90b430

Browse files
authored
repo sync
2 parents f334262 + 18561c0 commit f90b430

File tree

5 files changed

+154
-21
lines changed

5 files changed

+154
-21
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: Algolia Sync Single English Index
2+
3+
on:
4+
pull_request:
5+
types:
6+
- opened
7+
- reopened
8+
- synchronize
9+
- ready_for_review
10+
- unlocked
11+
12+
# This workflow requires a label in the format `sync-english-index-for-<PLAN@RELEASE>`
13+
jobs:
14+
updateIndices:
15+
name: Update English index for single version based on a label's version
16+
if: github.repository == 'github/docs-internal' && github.event.label.name.startsWith('sync-english-index-for-')
17+
runs-on: ubuntu-latest
18+
steps:
19+
- name: checkout
20+
uses: actions/checkout@5a4ac9002d0be2fb38bd78e4b4dbde5606d7042f
21+
- uses: actions/setup-node@56899e050abffc08c2b3b61f3ec6a79a9dc3223d
22+
with:
23+
node-version: 14.x
24+
- name: cache node modules
25+
uses: actions/cache@0781355a23dac32fd3bac414512f4b903437991a
26+
with:
27+
path: ~/.npm
28+
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
29+
restore-keys: |
30+
${{ runner.os }}-node-
31+
- name: npm ci
32+
run: npm ci
33+
- name: Get version from label
34+
id: getVersion
35+
run: |
36+
echo "::set-output name=version::$(github.event.label.name.split('sync-english-index-for-')[1])"
37+
- name: Sync English index for single version
38+
env:
39+
VERSION: ${{ steps.getVersion.outputs.version }}
40+
LANGUAGE: 'en'
41+
ALGOLIA_APPLICATION_ID: ${{ secrets.ALGOLIA_APPLICATION_ID }}
42+
ALGOLIA_API_KEY: ${{ secrets.ALGOLIA_API_KEY }}
43+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
44+
run: npm run sync-search

contributing/search.md

Lines changed: 77 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,18 @@
1-
## Search
1+
# Search
2+
3+
## Table of contents
4+
- [Overview](#overview)
5+
- [Production deploys](#production-deploys)
6+
- [Manual sync from a checkout](#manual-sync-from-a-checkout)
7+
- [Build without sync (dry run)](#build-without-sync-dry-run)
8+
- [Build and sync](#build-and-sync)
9+
- [Label-triggered Actions workflow](#label-triggered-actions-workflow)
10+
- [Files](#files)
11+
- [GitHub Actions workflow files](#github-actions-workflow-files)
12+
- [Code files](#code-files)
13+
14+
15+
## Overview
216

317
This site's search functionality is powered by [Algolia](https://www.algolia.com), a third-party service.
418

@@ -10,30 +24,77 @@ To see all existing search-related issues and pull requests, visit [github.com/g
1024

1125
---
1226

13-
## How it Works
27+
## Production deploys
28+
29+
A [GitHub Actions workflow](.github/workflows/sync-algolia-search-indices.yml) triggered by pushes to the `main` branch syncs the search data to Algolia. This process generates structured data for all pages on the site, compares that data to what's currently on Algolia, then adds, updates, or removes indices based on the diff of the local and remote data, being careful not to create duplicate records and avoiding any unnecessary (and costly) indexing operations.
30+
31+
The Actions workflow progress can be viewed (by GitHub employees) in the [Actions tab](https://github.com/github/docs/actions?query=workflow%3AAlgolia) of the repo.
32+
33+
Because the workflow runs after a branch is merged to `main`, there is a slight delay for search data updates to appear on the site.
34+
35+
## Manual sync from a checkout
36+
37+
It is also possible to manually sync the indices to Algolia from your local checkout of the repo, before your branch is merged to `main`.
38+
39+
**Prerequisite:** Make sure the environment variables `ALGOLIA_APPLICATION_ID` and `ALGOLIA_API_KEY` are set in your `.env` file. You can find these values on [Algolia](https://www.algolia.com/apps/ZI5KPY1HBE/api-keys/all).
40+
41+
### Build without sync (dry run)
42+
43+
To build all the indices without uploading them to Algolia's servers (this takes about an hour):
44+
```
45+
npm run sync-search-dry-run
46+
```
47+
To build indices for a specific language and/or version (this is much faster):
48+
```
49+
VERSION=<PLAN@RELEASE> LANGUAGE=<TWO-LETTER CODE> npm run sync-search-dry-run
50+
```
51+
You can set `VERSION` and `LANGUAGE` individually, too.
52+
53+
Substitute a currently supported version for `<PLAN@RELEASE>` and a currently supported two-letter language code for `<TWO-LETTER-CODE>`.
1454

15-
The search data is synced automatically using a [GitHub Actions workflow](.github/workflows/sync-algolia-search-indices.yml) that is triggered by pushes to the `main` branch. This process generates structured data for all pages on the site, compares that data to what's currently on Algolia, then adds, updates, or removes indices based on the diff of the local and remote data, being careful not to create duplicate records and avoiding any unnecessary (and costly) indexing operations.
55+
### Build and sync
1656

17-
The Actions workflow usually takes about five minutes, and the progress can be viewed (by GitHub employees) in the [Actions tab](https://github.com/github/docs/actions?query=workflow%3AAlgolia) of the repo.
57+
To build all the indices and sync them to Algolia (this also takes about an hour):
58+
```
59+
npm run sync-search
60+
```
61+
To build indices for a specific language and/or version and sync them to Algolia:
62+
```
63+
VERSION=<PLAN@RELEASE LANGUAGE=<TWO-LETTER CODE> npm run sync-search
64+
```
65+
You can set `VERSION` and `LANGUAGE` individually, too.
1866

19-
## Development
67+
Substitute a currently supported version for `<PLAN@RELEASE>` and a currently supported two-letter language code for `<TWO-LETTER-CODE>`.
2068

21-
In cases where a publicity event like GitHub Satellite or GitHub Universe demands a very tight shipping window, it is also possible to manually sync the indices with Algolia's servers from your local checkout of the repo, before your feature branch is merged to main. Manually syncing the indices can also be useful to test an unreleased GitHub Enterprise version or a translated language (Portuguese, Chinese, etc) that is not yet in production.
69+
## Label-triggered Actions workflow
2270

23-
To sync the indices from your development environment:
71+
Docs team members can use an Actions workflow on GHES release PRs by applying a label in this format:
72+
```
73+
sync-english-index-for-<PLAN@RELEASE>
74+
```
75+
This label will run a workflow on every push that **builds and uploads ONLY** the English index for the specified version. This means:
76+
77+
* The GHES content will be searchable at the same time the release PR is shipped, with no delay.
78+
* The GHES content will be searchable on staging throughout content creation.
79+
* No manual steps (unless you want to do a [dry run test](#build-without-sync-dry-run)).
2480

25-
1. Make sure the two required environment variables `ALGOLIA_APPLICATION_ID` and `ALGOLIA_API_KEY` are set in your `.env` file. These can be retrieved from the [Algolia site](https://www.algolia.com/apps/ZI5KPY1HBE/api-keys/all).
26-
2. Run `npm run sync-search-dry-run`. This takes a while to complete. It will prepare, test, and validate all the indices without actually uploading anything to Algolia's servers.
27-
3. Run `npm run sync-search` to prepare the indices again and upload them to the Algolia servers.
81+
Why do we need this? For our daily shipping needs, it's tolerable that search updates aren't available for up to an hour after the content goes live. But GHES releases are more time-sensitive, and writers have a greater need to preview search data on staging.
2882

2983
## Files
3084

31-
- [.github/workflows/sync-algolia-search-indices.yml](.github/workflows/sync-algolia-search-indices.yml) - the GitHub Actions workflow file that updates search indices whenever the main branch is updated.
32-
- [javascripts/search.js](javascripts/search.js) - the browser-side code that enables search using Algolia's [InstantSearch.js](https://github.com/algolia/instantsearch.js/) library.
33-
- [lib/algolia/client.js](lib/algolia/client.js) - a thin wrapper around the [algoliasearch](https://ghub.io/algoliasearch) Node.js module for interacting with the Algolia API.
34-
- [lib/algolia/search-index.js](lib/algolia/search-index.js) - a class for generating structured search data from repository content and syncing it with the remote Algolia service. This class has built-in validation to ensure that all records are valid before they're uploaded. This class also takes care of removing deprecated records, and compares existing remote records with the latest local records to avoid uploading records that haven't changed.
35-
- [script/sync-algolia-search-indices.js](script/sync-algolia-search-indices.js) - the script used by the Actions workflow to update search indices on our Algolia account. This can also be [run in the development environment](#development).
36-
- [tests/algolia-search.js](tests/algolia-search.js) - tests!
85+
### Actions workflow files
86+
87+
- [`.github/workflows/sync-algolia-search-indices.yml`](.github/workflows/sync-algolia-search-indices.yml) - Builds and syncs search indices whenever the `main` branch is pushed to (that is, on production deploys).
88+
- [`.github/workflows/dry-run-sync-algolia-search-indices.yml`](.github/workflows/dry-run-sync-algolia-search-indices.yml) - This workflow can be run manually (via `workflow_dispatch`) to do a dry run build of all the indices. Useful for confirming that the indices can build without erroring out.
89+
- [`.github/workflows/sync-single-english-algolia-index.yml`](.github/workflows/sync-single-english-algolia-index.yml) - This workflow is run when a label in the right format is applied to a PR. See "[Label-triggered Actions workflow](#label-triggered-actions-workflow)" for details.
90+
91+
### Code files
92+
93+
- [javascripts/search.js](javascripts/search.js) - The browser-side code that enables search using Algolia's [InstantSearch.js](https://github.com/algolia/instantsearch.js/) library.
94+
- [lib/algolia/client.js](lib/algolia/client.js) - A thin wrapper around the [algoliasearch](https://ghub.io/algoliasearch) Node.js module for interacting with the Algolia API.
95+
- [lib/algolia/search-index.js](lib/algolia/search-index.js) - A class for generating structured search data from repository content and syncing it with the remote Algolia service. This class has built-in validation to ensure that all records are valid before they're uploaded. This class also takes care of removing deprecated records, and compares existing remote records with the latest local records to avoid uploading records that haven't changed.
96+
- [script/sync-algolia-search-indices.js](script/sync-algolia-search-indices.js) - The script used by the Actions workflow to update search indices on our Algolia account. This can also be [run in the development environment](#development).
97+
- [tests/algolia-search.js](tests/algolia-search.js) - Tests!
3798

3899
## Indices
39100

lib/algolia/sync.js

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,43 @@ const allVersions = require('../all-versions')
1515
// e.g. `github-docs-dotcom-en.json` and `github-docs-2.14-ja.json`
1616
module.exports = async function syncAlgoliaIndices (opts = {}) {
1717
if (opts.dryRun) {
18-
console.log('This is a dry run! The script will abort without uploading anything.')
18+
console.log('This is a dry run! The script will build the indices locally but not upload anything.\n')
1919
rimraf(cacheDir)
2020
mkdirp(cacheDir)
2121
}
2222

23+
if (opts.language) {
24+
if (!Object.keys(languages).includes(opts.language)) {
25+
console.log(`Error! ${opts.language} not found. You must provide a currently supported two-letter language code.`)
26+
process.exit(1)
27+
}
28+
}
29+
30+
if (opts.version) {
31+
if (!Object.keys(allVersions).includes(opts.version)) {
32+
console.log(`Error! ${opts.version} not found. You must provide a currently supported version in <PLAN@RELEASE> format.`)
33+
process.exit(1)
34+
}
35+
}
36+
37+
// build indices for a specific language if provided; otherwise build indices for all languages
38+
const languagesToBuild = opts.language
39+
? Object.keys(languages).filter(language => language === opts.language)
40+
: Object.keys(languages)
41+
42+
// build indices for a specific version if provided; otherwise build indices for all veersions
43+
const versionsToBuild = opts.version
44+
? Object.keys(allVersions).filter(version => version === opts.version)
45+
: Object.keys(allVersions)
46+
47+
console.log(`Building indices for ${opts.language || 'all languages'} and ${opts.version || 'all versions'}.\n`)
48+
2349
// Exlude WIP pages, hidden pages, index pages, etc
2450
const indexablePages = await findIndexablePages()
2551

2652
// Build and validate all indices
27-
for (const languageCode in languages) {
28-
for (const pageVersion in allVersions) {
53+
for (const languageCode of languagesToBuild) {
54+
for (const pageVersion of versionsToBuild) {
2955
// if GHES, resolves to the release number like 2.21, 2.22, etc.
3056
// if FPT, resolves to 'dotcom'
3157
// if GHAE, resolves to 'ghae'

lib/liquid-tags/extended-markdown.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ const tags = {
1111
danger: 'border rounded-1 mb-4 p-3 border-red bg-red-light f5'
1212
}
1313

14-
const template = '<div class="extended-markdown {{ tagName }} {{ classes }}">\n{{ output }}\n</div>'
14+
const template = '<div class="extended-markdown {{ tagName }} {{ classes }}">{{ output }}</div>'
1515

1616
class ExtendedMarkdown extends Liquid.Block {
1717
async render (context) {

script/sync-algolia-search-indices.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ main()
1414
async function main () {
1515
const sync = require('../lib/algolia/sync')
1616
const opts = {
17-
dryRun: 'DRY_RUN' in process.env
17+
dryRun: 'DRY_RUN' in process.env,
18+
language: process.env.LANGUAGE,
19+
version: process.env.VERSION
1820
}
1921
await sync(opts)
2022
}

0 commit comments

Comments
 (0)