How to Contribute to Solr Documentation

The Lucene/Solr project has made it easy for anyone to contribute to the Solr Reference Guide with a patch.

The Guide is written in simple AsciiDoc-formatted files, and the source lives in the main Lucene/Solr source repository, right alongside the code.

The following sections give an overview of how to work with AsciiDoc-format files, how our documentation is generated, and how to do a Ref Guide release.

Once you have a patch you’d like to contribute, you can submit it with a JIRA issue, the same as any other patch. See also the Solr wiki section on How To Contribute for information on submitting patches.

AsciiDoc Syntax Cheatsheet

The definitive manual on AsciiDoc syntax is in the Asciidoctor User Manual. To help people get started, however, here is a simpler cheat sheet.

AsciiDoc vs Asciidoctor Syntax

We use tools from the Asciidoctor project to build the HTML version of the Ref Guide. Asciidoctor is a Ruby port of the original AsciiDoc project, which was mostly abandoned several years ago.

While much of the syntax between the two is the same, there are many conventions supported by Asciidoctor that did not exist in AsciiDoc. While the Asciidoctor project has tried to provide back-compatibility with the older project, that may not be true forever. For this reason, it’s strongly recommended to only use the Asciidoctor User Manual as a reference for any syntax that’s not described here.

Basic AsciiDoc Syntax

Bold

Put asterisks around text to make it bold.

More info: http://asciidoctor.org/docs/user-manual/#bold-and-italic

Italics

Use underlines on either side of a string to put text into italics.

More info: http://asciidoctor.org/docs/user-manual/#bold-and-italic

Headings

Equal signs (=) are used for heading levels. Each equal sign is a level. Each page can only have one top level (i.e., only one section with a single =).

Levels should be appropriately nested. During the build, validation occurs to ensure that level 3s are preceded by level 2s, level 4s are preceded by level 3s, etc. Including out-of-sequence heading levels (such as a level 3 then a level 5) will not fail the build, but will produce an error.

More info: http://asciidoctor.org/docs/user-manual/#sections

Code Examples

Use backticks ` for text that should be monospaced, such as code or a class name in the body of a paragraph.

More info: http://asciidoctor.org/docs/user-manual/#mono

Longer code examples can be separated from text with source blocks. These allow defining the syntax being used so the code is properly highlighted.

Example Source Block
[source,xml]
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />

If your code block will include line breaks, put 4 hyphens (----) before and after the entire block.

More info: http://asciidoctor.org/docs/user-manual/#source-code-blocks

Source Block Syntax Highlighting

The HTML output uses Rouge to add syntax highlighting to code examples. This is done by adding the language of the code block after the source, as shown in the above example source block (xml in that case).

Rouge has a long selection of lexers available. You can see the full list at https://github.com/rouge-ruby/rouge/wiki/List-of-supported-languages-and-lexers. Use one of the valid short names to get syntax highlighting for that language.

Ideally, we will have an appropriate lexer to use for all source blocks, but that’s not possible. When in doubt, choose text, or leave it blank.

Importing Code Snippets from Other Files

The build system has the ability to "include" snippets located in other files — even non-AsciiDoc files such as *.java source code files.

Snippets are bounded by "tag" comments placed at the start and end of the section you would like to import. Opening tags look like: // tag::snippetName[]. Closing tags follow the format: // end::snippetName[]. Snippets can be dropped into an .adoc file using an include directive, following the format: include::PathToFileWithSnippet[tag=snippetName]. Note that when relative paths are provided in these directives, those paths are resolved relative to the location of the AsciiDoc file that the include appears in.

Snippets can be included directly from any file in the Lucene/Solr GIT repo by refering to a solr-root-path variable prior to the file path, for example:

[source,java,indent=0]
----
include::{solr-root-path}core/src/java/org/apache/solr/core/SolrCore.java[tag=something]
----

When building the Guide, the solr-root-path attribute will be automatically set correctly for the (temporary) build/solr-ref-guide/content directory used by Ant.

In order for editors (such as ATOM) to be able to offer "live preview" of the *.adoc files using these includes, the solr-root-path attribute must also be set as a document level attribute in each file, with the correct relative path.

For example, using-solrj.adoc sets solr-root-path in its header, along with an example-source-dir attribute (that depends on solr-root-path) in order to reduce redundancy in the many include:: directives it specifies…​

= Using SolrJ
:solr-root-path: ../../
:example-source-dir: {solr-root-path}solrj/src/test/org/apache/solr/client/ref_guide_examples/
...
[source,java,indent=0]
----
include::{example-source-dir}UsingSolrJRefGuideExamplesTest.java[tag=solrj-solrclient-timeouts]
----
...
[source,java,indent=0]
----
include::{example-source-dir}UsingSolrJRefGuideExamplesTest.java[tag=solrj-other-apis]
----
...

For more information on the include directive, see the documentation at http://asciidoctor.org/docs/user-manual/#include-partial.

Block Titles

Titles can be added to most blocks (images, source blocks, tables, etc.) by simply prefacing the title with a period (.). For example, to add a title to the source block example above:

.Example ID field
[source,xml]
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false" />

When converting content to HTML, Asciidoctor will automatically render many link types (such as http: and mailto:) without any additional syntax.

However, you can add a name to a link by adding the URI followed by square brackets:

http://lucene.apache.org/solr[Solr Website]

A warning up front, linking to other pages can be a little bit painful. There are slightly different rules depending on the type of link you want to create, and where you are linking from.

The build process includes a validation for internal or inter-page links, so if you can build the docs locally, you can use that to verify you constructed your link properly (or pay attention to the Jenkins build after your commit).

With all of the below examples, you can add text to display as the link title by adding a comma after the section reference followed by the display text, as in:

<<schema-api.adoc#modify-the-schema,Modify the Schema>>

To link to an anchor (or section title) on the same page, you can simply use double angle brackets (<< >>) around the anchor/heading/section title you want to link to. Any section title (a heading that starts with equal signs) automatically becomes an anchor during conversion and is available for deep linking.

Example

If I have a section on a page that looks like this (from defining-fields.adoc):

== Field Properties

Field definitions can have the following properties:

To link to this section from another part of the same defining-fields.adoc page, I simply need to put the section title in double angle brackets, as in:

See also the <<Field Properties>> section.

The section title will be used as the display text; to customize that add a comma after the the section title, then the text you want used for display.

More info: http://asciidoctor.org/docs/user-manual/#internal-cross-references

When linking to any section (on the same page or another one), you must also be aware of any pre-defined anchors that may be in use (these will be in double brackets, like [[ ]]). When the page is converted, those will be the references your link needs to point to.

Example

Take this example from configsets-api.adoc:

[[configsets-create]]
== Create a ConfigSet

To link to this section, there are two approaches depending on where you are linking from:

  • From the same page, simply use the anchor name: <<configsets-create>>.

  • From another page, use the page name and the anchor name: <<configsets-api.adoc#configsets-create>>.

To link to another page or a section on another page, you must refer to the full filename and refer to the section you want to link to.

Unfortunately, when you want to refer the reader to another page without deep-linking to a section, you cannot simply put the other file name in angle brackets and call it a day. You must always link to a specific section. If all you want is a reference to the top of another page, you can use the implicit id of the page — the filename w/o the .adoc extension — as your anchor reference.

Example

To construct a link to the upgrading-solr.adoc page, we need to refer to the file name (upgrading-solr.adoc), then use the page id (upgrading-solr) as the anchor reference. As in:

For more information about upgrades, see <<upgrading-solr.adoc#upgrading-solr>>.

Linking to a section is the same conceptually as linking to the top of a page, you just need to take a little extra care to format the anchor ID in your link reference properly.

When you link to a section on another page, you must make a simple conversion of the title into the format the section ID will be created during the conversion. These are the rules that transform the sections:

  • All characters are lower-cased.

    • Using security.json with Solr becomes using security.json with solr

  • All non-alpha characters are removed, with the exception of hyphens (so all periods, commas, ampersands, parentheses, etc., are stripped).

    • using security.json with solr becomes using security json with solr

  • All whitespaces are replaced with hyphens.

    • using security json with solr becomes using-security-json-with-solr

Example

The file schema-api.adoc has a section "Modify the Schema" that looks like this:

== Modify the Schema

`POST /_collection_/schema`

To link from to this section from another page, you would create a link structured like this:

  • the file name of the page with the section (schema-api.adoc),

  • then the hash symbol (#),

  • then the converted section title (modify-the-schema),

  • then a comma and any link title for display.

The link in context would look like this:

For more information, see the section <<schema-api.adoc#modify-the-schema,Modify the Schema>>.

More info: http://asciidoctor.org/docs/user-manual/#inter-document-cross-references

Ordered and Unordered Lists

AsciiDoc supports three types of lists:

  • Unordered lists

  • Ordered lists

  • Labeled lists

Each type of list can be mixed with the other types. So, you could have an ordered list inside a labeled list if necessary.

Unordered Lists

Simple bulleted lists need each line to start with an asterisk (*). It should be the first character of the line, and be followed by a space.

These lists also need to be separated from the

More info: http://asciidoctor.org/docs/user-manual/#unordered-lists

Ordered Lists

Numbered lists need each line to start with a period (.). It should be the first character of the line, and be followed by a space.

This style is preferred over manually numbering your list.

More info: http://asciidoctor.org/docs/user-manual/#ordered-lists

Labeled Lists

These are like question & answer lists or glossary definitions. Each line should start with the list item followed by double colons (::), then a space or new line.

Labeled lists can be nested by adding an additional colon (such as :::, etc.).

If your content will span multiple paragraphs or include source blocks, etc., you will want to add a plus sign (+) to keep the sections together for your reader.

We prefer this style of list for parameters because it allows more freedom in how you present the details for each parameter. For example, it supports ordered or unordered lists inside it automatically, and you can include multiple paragraphs and source blocks without trying to cram them into a smaller table cell.

More info: http://asciidoctor.org/docs/user-manual/#labeled-list

Images

There are two ways to include an image: inline or as a block.

Inline images are those where text will flow around the image. Block images are those that appear on their own line, set off from any other text on the page.

Both approaches use the image tag before the image filename, but the number of colons after image define if it is inline or a block. Inline images use one colon (image:), while block images use two colons (image::).

Block images automatically include a caption label and a number (such as Figure 1). If a block image includes a title, it will be included as the text of the caption.

Optional attributes allow you to set the alt text, the size of the image, if it should be a link, float and alignment.

More info: http://asciidoctor.org/docs/user-manual/#images

Tables

Tables can be complex, but it is pretty easy to make a basic table that fits most needs.

Basic Tables

The basic structure of a table is similar to Markdown, with pipes (|) delimiting columns between rows:

|===
| col 1 row 1 | col 2 row 1|
| col 1 row 2 | col 2 row 2|
|===

Note the use of |=== at the start and end. For basic tables that’s not exactly required, but it does help to delimit the start and end of the table in case you accidentally introduce (or maybe prefer) spaces between the rows.

Header Rows

To add a header to a table, you need only set the header attribute at the start of the table:

[options="header"]
|===
| header col 1 | header col 2|
| col 1 row 1 | col 2 row 1|
| col 1 row 2 | col 2 row 2|
|===

Defining Column Styles

If you need to define specific styles to all rows in a column, you can do so with the attributes.

This example will center all content in all rows:

[cols="2*^" options="header"]
|===
| header col 1 | header col 2|
| col 1 row 1 | col 2 row 1|
| col 1 row 2 | col 2 row 2|
|===

Alignments or any other styles can be applied only to a specific column. For example, this would only center the last column of the table:

[cols="2*,^" options="header"]
|===
| header col 1 | header col 2|
| col 1 row 1 | col 2 row 1|
| col 1 row 2 | col 2 row 2|
|===

Many more examples of formatting:

More Options

Tables can also be given footer rows, borders, and captions. You can determine the width of columns, or the width of the table as a whole.

CSV or DSV can also be used instead of formatting the data in pipes.

More info: http://asciidoctor.org/docs/user-manual/#tables

Admonitions (Notes, Warnings)

AsciiDoc supports several types of callout boxes, called "admonitions":

  • NOTE

  • TIP

  • IMPORTANT

  • CAUTION

  • WARNING

It is enough to start a paragraph with one of these words followed by a colon (such as NOTE:). When it is converted to HTML, those sections will be formatted properly - indented from the main text and showing an icon inline.

You can add titles to admonitions by making it an admonition block. The structure of an admonition block is like this:

.Title of Note
[NOTE]
====
Text of note
====

In this example, the type of admonition is included in square brackets ([NOTE]), and the title is prefixed with a period. Four equal signs give the start and end points of the note text (which can include new lines, lists, code examples, etc.).

More info: http://asciidoctor.org/docs/user-manual/#admonition

STEM Notation Support

We have set up the Ref Guide to be able to support STEM notation whenever it’s needed.

The AsciiMath syntax is supported by default, but LaTeX syntax is also available.

To insert a mathematical formula inline with your text, you can simply write:

stem:[a//b]

MathJax.js will render the formula as proper mathematical notation when a user loads the page. When the above example is converted to HTML, it will look like this to a user: \$a//b\$

To insert LaTeX, preface the formula with latexmath instead of stem:

latexmath:[tp \leq 1 - (1 - sim^{rows})^{bands}]

Long formulas, or formulas which should to be set off from the main text, can use the block syntax prefaced by stem or latexmath:

[stem]
++++
sqrt(3x-1)+(1+x)^2 < y
++++

or for LaTeX:

[latexmath]
++++
[tp \leq 1 - (1 - sim^{rows})^{bands}]
++++

More info: https://asciidoctor.org/docs/user-manual/#stem-in

Tools for Working with AsciiDoc Files

AsciiDoc vs Asciidoctor

The Solr Ref Guide is written in AsciiDoc format. This format is generally considered an extension of Markdown, because it has support for tables of contents, better table support, and other features that make it more appropriate for writing technical documentation.

We are using a version of the AsciiDoc syntax along with tools from an open source project called Asciidoctor. This provides full support for the AsciiDoc syntax, but replaces the original Python processor with one written in Ruby. There is a Java implementation, known as AsciidoctorJ. Further extensions from the original AsciiDoc project include support for font-based icons and UI elements.

Helpful Tools

You can write AsciiDoc without any special tools. It’s simply text, with familiar syntax for bold (*) and italics (_).

Having some tools in your editor is helpful, though.

Doc Preview

This allows you to see your document in something close to what it might appear like when output to HTML.

The following information is from http://asciidoctor.org/docs/editing-asciidoc-with-live-preview.

  • Atom has AsciiDoc Preview, which gives you a panel that updates as you type. There are also a couple of other plugins to support AsciiDoc format and auto-complete.

  • There is a Live Preview browser plugin for Chrome, Firefox and Opera which allow you to open your AsciiDoc page in the browser. It will also update as you type.

  • There is also an Intellij IDEA plugin to support AsciiDoc format.

Working with HTML Templates

The Solr Ref Guide uses Jekyll to build the HTML version of the site.

What is Jekyll?

Jekyll is a static site generator, meaning that it takes some set of documents and produces HTML pages. It allows for templating of the pages, so each page has the same look and feel without having to code headers, footers, logos, etc., into every page.

Jekyll is an open source project written in Ruby, online at https://jekyllrb.com/.

How We Use Jekyll

The following sections describe the main features of Jekyll that you will encounter while working with the Solr Ref Guide.

Jekyll-Asciidoctor Plugin

We use a plugin for Jekyll from the Asciidoctor project to integrate Jekyll with Asciidoc formatted content. The source for the plugin is available at https://github.com/asciidoctor/jekyll-asciidoc.

This plugin allows us to use Asciidoctor-style variables with Jekyll.

_config.yml

The _config.yml is a global configuration file that drives many of the options used when building the site (particularly in our use of Jekyll).

We have template-ized _config.yml, so in our use of Jekyll you will find it in solr/solr-ref-guide/src as _config.yml.template. This allows us to define some variables during the build and use common Lucene/Solr build parameters (such as project versions).

Front Matter

Front matter for Jekyll is similar to a header that defines the title of the page, and other variables that may be helpful (or even required) when rendering the page.

Every document that will be converted to HTML must include at least the page title at the top of the page. Page titles are defined with a single equal sign (=) followed by the title that will appear at the top of the page (such as = Topic of the Page).

Many guides to Jekyll also say that defining the layout in the front matter is required. However, since we only use one layout for all pages, we have defined this as a default.

The Solr Ref Guide uses the front matter to define some custom attributes on a per-page basis:

  • page-children - ordered list of child pages, this is used to build the site navigation menu that appears to the left of each page’s content.

Other page-level elements can also be defined, such as an Asciidoctor attribute that should apply only to that page, but are not needed on a regular basis.

The format for adding any parameter to the front matter is to use colons on both sides of the parameter, followed by the value for the parameter (such as :page-toc: false).

Table of Contents

There are some optional custom attributes that can be defined in pages to affect the Table of Contents presentation in Jekyll:

toclevels
Changes how "deep" the TOC will be in terms of nested section/sub-section titles (default = 2). Example: :toclevels: 1.
page-show-toc
If this is false, then no TOCs will be generated for the page at all. The default is true, so can usually be left undefined. Example :page-show-toc: false.

Layouts

Layouts define the "look and feel" of each page. Jekyll uses Liquid for page templates.

For our implementation of Jekyll, layouts are found in solr-ref-guide/src/_layouts.

We currently use the _layouts/default.html layout for overall page structure, for almost all pages and _layouts/page.html for the page-level content. The page.html layout is inserted into the default.html layout.

The main page (index.html) of the Ref Guide uses the _layouts/home.html layout. It also still uses _layouts/page.html for the page-level content. This is done because index.html has some special formatting and rules for how to define the page.

Includes

Include files are (usually) small HTML files that are pulled into a layout when a page is being built. They are Liquid templates that define an area of the page. This allows flexibility across layouts - all pages can have the same header without duplicating code, but different pages could have different menu options.

Include files that we use define the top navigation, the page header, and the page footer.

For our implementation of Jekyll, include files are found in solr-ref-guide/src/_includes.

Data Files

Data files include data such as lists that should be included in each page. The left-hand navigation menu is an example of a data file. However, in our build, the navigation is built from the page-children hierarchies defined on parent pages.

For our implementation of Jekyll, data files are found in solr-ref-guide/src/_data.

Asciidoctor Slim Templates

Jekyll creates all of the page elements we do not define in each .adoc file: the header, footer, top nav, sidebar nav, and other parts of the page that we don’t worry about as we write the content of a page.

Asciidoctor converts the content in each .adoc file into HTML and inserts it into the Jekyll page layout we have defined (see Layouts) to make the individual HTML files that make up the Ref Guide.

While we have unlimited control over styling page content via CSS, without creating custom Asciidoctor-specific plugins or templates there is little out-of-the-box control over the elements, classes, etc. that make up the HTML pages.

In order to better support HTML5, we have customized Asciidoc’s default conversion with templates found in the _templates directory. These templates use Slim as the template engine.

Since these templates dictate the very structure of the HTML of our content, customizing these should only be attempted in rare instances and with extensive testing for unforeseen impacts.

Using Bootstrap

The HTML files include Bootstrap (v4.1.3 as of April 2020, see _includes/head.html to confirm the Bootstrap version currently being used), so all of the components of Bootstrap are available.

The design of the Ref Guide makes extensive use of Bootstrap classes to layout the page via the Liquid templates and our customized Asciidoctor templates.

When we want to use additional components of Boostrap that require specific HTML constructs, we must define those within the page content itself (using either <div> elements in the content or with Asciidoctor’s roles, discussed in the section).

Asciidoctor Roles

Asciidoctor helpfully provides a way to define custom <div> classes in .adoc files, as long as we understand how to use it.

Asciidoctor does not call these "divs" or "classes", but instead "roles". We can give any content a role - to images, content blocks (such as [source] or [NOTE], etc.), even a word in the middle of a sentence.

Because roles are so flexible, they only apply to the thing - the word, content block, image, etc. - they are directly applied to. This means that if we want an entire section of content to be given a specific role in the HTML (i.e., enclosed in a <div>), then we need to put the content in a block.

For more on Roles in Asciidoctor, see Role in the Asciidoctor User Guide.
Creating Tabbed Sections

Hopefully a little bit of background on roles is helpful to understanding the rest of what we’ll do to create a tabbed section in a page.

See the Bootstrap docs on nav tabs for details on how to use tabs and pills with Bootstrap. As a quick overview, tabs in Bootstrap are defined like this:

<ul class="nav nav-pills"> 
  <li class="active"><a data-toggle="pill" href="#sec1">Section 1</a></li>
  <li><a data-toggle="pill" href="#sect2">Section 2</a></li>
</ul>

<div class="tab-content"> 
  <div id="sect1" class="tab-pane active"> 
    <h3>Section 1</h3>
    <p>Some content.</p>
  </div>
  <div id="sect2" class="tab-pane">
    <h3>Section 2</h3>
    <p>Some other content.</p>
  </div>
</div>
1This section creates an unordered list with a line item for each tab. The data-toggle and class parameters are what tell Bootstrap how to render the content.
2Note the class defined here: <div class="tab-content">. This defines that what follows is the content that will make up the panes of our tabs. We will need to define these in our document.
3In our document, we need to delineate the separate sections of content that will make up each pane.

We have created some custom JavaScript that will do part of the above for us if we assign the proper roles to the blocks of content that we want to appear in the tab panes. To do this, we can use Asciidoctor’s block delimiters to define the tabbed content, and the content between the tab.

  1. Define an "open block" (an unformatted content block), and give it the role .dynamic-tabs. An open block is defined by two hyphens on a line before the content that goes in the block, and two hyphens on a line after the content to end the block. We give a block a role by adding a period before the role name, like this:

    [.dynamic-tabs]
    --
    The stuff we'll put in the tabs will go here.
    --
  2. Next we need to define the content for the tabs between the open block delimiters.
    1. We enclose each tab pane in another type of block, and "example" block. This allows us to include any kind of content in the block and be sure all of the various types of elements (heading, text, examples, etc.) are included in the pane.
    2. We give the example block another role, tab-pane, and we must make sure that each pane has a unique ID. We assign IDs with a hash mark (\#) followed by the ID value (#sect1).
    3. We also need to define a label for each tab. We do this by adding another role, tab-label to the content we want to appear as the name of the tab.
    4. In the end one pane will look like this:

      [example.tab-pane#sect1] 
      ==== 
      [.tab-label]*Section 1*  
      My content...
      ====
      1When we define the example block with [example], it’s followed by .tab-pane#sect1 as the class (each class separated by a period .) and the ID defined in the tab definition earlier. Those will become the classes (class="tab-pane active") and ID (id="sect1") in the resulting HTML.
      2Example blocks are delimited by 4 equal signs (====) before and after the enclosed content.
      3The words "Section 1" will appear in the HTML page as the label for this tab.
    5. Create [example.tab-pane#id] sections for each tab, until you finally end up with something that looks like this:

      [.dynamic-tabs]
      --
      [example.tab-pane#sect1]
      ====
      [.tab-label]*Section 1*
      My content...
      ====
      
      [example.tab-pane#sect2]
      ====
      [.tab-label]*Section 2*
      My content...
      ====
      --

Building the HTML Site

An Ant target ant build-site when run from the solr/solr-ref-guide directory will build the full HTML site (found in solr/build/solr-ref-guide/html-site).

This target builds the navigation for the left-hand menu, and converts all .adoc files to .html, including navigation and inter-document links.

Building the HTML has several dependencies that will need to be installed on your local machine. Review the README.adoc file in the solr/solr-ref-guide directory for specific details.

Using the Gradle build does not require any local dependencies. Simply use ./gradlew buildSite to generate the HTML files using Gradle (these will be found in solr/solr-ref-guide/build/html-site).

Build Validation

When you run ant build-site to build the HTML, several additional validations occur during that process. See solr-ref-guide/tools/CheckLinksAndAnchors.java for details of what that tool does to validate content.

Ref Guide Publication Process

This section details how to build the Guide for publication.

Guide Publication Overview

  1. Build and publish the DRAFT version.
  2. Continue to update docs as needed while Lucene/Solr artifact VOTE thread is ongoing.
  3. After VOTE has passed, build and publish final version to overwrite DRAFT watermarked pages.

Pre-Requisites

In order to build the Ref Guide, you must have the following:

  • You have checked out the Lucene/Solr source code on the machine you will be doing the release from.

  • You have Subversion installed. This is needed for committing the HTML files to the production website repo.

  • You have installed Ruby and several gems described in the README file located at solr/solr-ref-guide/README.adoc in your Lucene/Solr checkout.

  • All builds must be done from the release branch the Guide is for.

Builds are available via Jenkins for several branches. However, these HTML pages will have the DRAFT status noted in them and are not suitable for final production publishing.

Build the DRAFT Guide

The build process generates the page hierarchy and builds the HTML pages with custom templates the Lucene/Solr project has defined.

To build the HTML:

  1. Navigate to ./solr/solr-ref-guide, where the Guide’s build.xml is located.
  2. Run:

    $ ant clean default

    This will produce pages with a DRAFT watermark across them. While these are fine for initial DRAFT publication, see the section Publish the Final Guide for steps to produce final production-ready HTML pages.

  3. The resulting Guide will be in solr/build/solr-ref-guide. The HTML files themselves will be in solr/build/solr-ref-guide/html-site.

Upload to the Website

Push the Guide directly to production via Subversion import from where you built it.

svn -m "Add Ref Guide for Solr 7.7" import <checkoutroot>/solr/build/solr-ref-guide/html-site https://svn.apache.org/repos/infra/websites/production/lucene/content/solr/guide/7_7

Confirm you can browse to Guide manually by going to the new URL. For example: https://lucene.apache.org/solr/guide/7_7

Publish the Final Guide

There are two steps to publishing the Guide: first, uploading the DRAFT pages with the production-ready version; and second, updating links to point to the new Guide.

Update DRAFT for Release

Since the Guide has already been uploaded to SVN, you need to overwrite the existing files in svn with a version of the production version of the guide:

Build Production Guide

Build the Guide locally with a parameter for the Guide version. This requires the same pre-requisites from above.

$ant clean default -Dsolr-guide-version=X.Y

where X.Y is the version you want to publish (i.e., 7.7).

The -Dsolr-guide-version system property is optional if you build drafts locally or as pre-publication DRAFTs (i.e., not for publication). By default the build system uses the lucene/version.properties file in the current branch and assumes this is a DRAFT build which will have a DRAFT watermark and other labels on the pages. Including the -Dsolr-guide-version system property ensures the DRAFT watermark and labels are removed from the HTML files.

Pull Production Repo and Upload New Files

  1. Checkout the directory you need to update from the svn production repo:

    $ svn co https://svn.apache.org/repos/infra/websites/production/lucene/content/solr/guide/<dir>
    • This command checks out the Guide version directory into a local subdirectory with the same name as the version (such as "7_7"). You can provide a better name locally if you prefer by adding it to the end of the command shown above.

    • Don’t shortcut this and download the whole production website. It will take an incredibly long time and that will feel like forever.

  2. Copy the files from the build location to the checked out Guide directory. For example, if we needed to replace the Guide for Solr 7.7, we’d do cp -r ./solr/build/solr-ref-guide/html-site 7_7/.
  3. Use svn status to see the files modified. If there are any pages added or deleted, use svn add <file> or svn rm <file> as needed.
  4. Commit the changes: svn commit -m "Update production 7.7 Ref Guide"

Verify Upload Successful

Spot-check a few pages to verify that the DRAFT watermark is gone, and also that Solr Javadocs link back to Lucene’s correctly (the UpdateRequestProcessor page has a lot of Javadoc links).

The only edit we need to do in the website itself is adding a link to the latest guide to /solr/guide.

Edit guide.md in staging

  1. Look at https://lucene.staged.apache.org/solr/guide and see if the RM already has updated it. If not, continue
  2. You can check out and push changes or edit the file directly in GitHub: https://github.com/apache/lucene-site/blob/master/content/pages/solr/guide.md by clicking the edit button and then adding a commit message.
  3. Verify that the staged version looks good (the link will not work in staging though)

Publish the changes to production

You can use your favourite git client to merge master into branch production. Or you can use GitHub website:

  1. Make a new pull request from https://github.com/apache/lucene-site/compare/production%2E%2E%2Emaster
  2. Note: If there are other changes staged, you will see those as well if you merge master into production
  3. Click the "Merge" button on the PR

The ordinary Solr release process will update the LUCENE_LATEST_RELEASE property of the website, which will ensure that Ref Guide URLs without a version in the path (e.g., /solr/guide/mypage.adoc) will automatically redirect to the latest Guide.