Let's Treat Docs Like CodeJekyll2023-10-28T19:46:58+00:00https://www.docslikecode.com/https://www.docslikecode.com/https://www.docslikecode.com/articles/protecting-codeowners-file2023-10-01T00:00:00+00:002023-10-01T00:00:00+00:00https://www.docslikecode.com
<h1 id="designate-a-review-team-for-a-directory-or-collection-of-files">Designate a review team for a directory or collection of files</h1>
<p>With GitHub, you have the capability to designate a review team. This setup works well for a scenario where a <code class="language-plaintext highlighter-rouge">docs</code> directory should be completely controlled by the documentation team. With a <a href="https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners">CODEOWNERS</a> file configuration, the documentation team does not need to ask for other reviewers for small changes like a typo or grammar fix. When a team member’s account name or team name is in the <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file, you can protect the branch or folder from merges from any account not found in the file.</p>
<p>A <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file can be stored in a directory, or in the <code class="language-plaintext highlighter-rouge">.github</code> folder, where many configuration files are stored by default. You can protect a branch or multiple branches based on a naming pattern match using <a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches">protected branches</a>.</p>
<p>A straightforward example involves protecting the <code class="language-plaintext highlighter-rouge">docs</code> folder in the <code class="language-plaintext highlighter-rouge">main</code> branch, where the <code class="language-plaintext highlighter-rouge">main</code> branch is the branch used to publish the documentation. In this example, the org name is <code class="language-plaintext highlighter-rouge">justwriteclick</code> and the username is <code class="language-plaintext highlighter-rouge">annegentle</code>. You would name the file <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> and store it in a <code class="language-plaintext highlighter-rouge">docs</code> directory.</p>
<p>Example <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>@justwriteclick/annegentle
</code></pre></div></div>
<p>You can also use an email address instead of an account name. See an example with lots of use cases in the GitHub documentation <a href="https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners#example-of-a-codeowners-file">Example of a CODEOWNER file</a>.</p>
<p>Then, make sure that the branch is protected using the repository’s <strong>Setting</strong> > <strong>Branches</strong> > <strong>Branch protection rules</strong> > <strong>Add protection rule</strong> button. Enter <code class="language-plaintext highlighter-rouge">main</code> for the <strong>Branch name pattern</strong> and then select <strong>Require a pull request before merging</strong>. The settings expand so you can also choose <strong>Require review from Code Owners</strong>. Once you have the settings, click the <strong>Create</strong> button at the bottom of the page. More details are in the <a href="https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/managing-protected-branches/about-protected-branches">GitHub Docs</a>.</p>
<p><img src="../../images/branch-protection-rule.png" alt="GitHub Branch protection rules settings." /></p>
<p>To see an example of this setup, look at the Microsoft 365 community documentation repository at <a href="https://github.com/MicrosoftDocs/microsoft-365-community/">https://github.com/MicrosoftDocs/microsoft-365-community/</a>. The <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file contains a team name, <code class="language-plaintext highlighter-rouge">@microsoftdocs/officedocs-admin</code>, and those team members can review and merge the list of documents in the <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file. The documents contain configuration information as well as the <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file itself.</p>
<p>Example <code class="language-plaintext highlighter-rouge">CODEOWNERS</code> file from MicrosoftDocs:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docfx.json @microsoftdocs/officedocs-admin
.openpublishing.build.ps1 @microsoftdocs/officedocs-admin
.openpublishing.publish.config.json @microsoftdocs/officedocs-admin
CODEOWNERS @microsoftdocs/officedocs-admin
.acrolinx-config.edn @microsoftdocs/officedocs-admin
</code></pre></div></div>
<p>Think about ways you can protect your branches with a known group of reviewers. This workflow builds trust and safety while also ensuring you can move fast when needed in a larger team and repository setting.</p>
<p><a href="https://www.docslikecode.com/articles/protecting-codeowners-file/">Protecting a Branch so Only the Docs Team Merges and Publishes</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on October 01, 2023.</p>
https://www.docslikecode.com/articles/sysdig-adopting-docs-as-code2022-07-11T00:00:00+00:002022-07-11T00:00:00+00:00Radhika Puthiyetathhttps://www.docslikecode.com
<p>Originally published in the <a href="https://sysdig.com/blog/adopting-docs-as-code/">Sysdig Blog</a>.</p>
<p>Thanks to the yearly Hackathons at Sysdig, we’ve recently democratized documentation creation by embracing the docs-as-code philosophy. Similar to our source code practices, product documentation has been version controlled, subjected to the same gatekeeping systems, and auto-delivered by using the same CI/CD pipeline.</p>
<p><img src="/images/sysdig/sysdig-process.png" alt="" /></p>
<p>In this article, you’ll read about the journey of Sysdig documentation. You will also learn how we finally arrived at the current scheme of things, how it enables us to be effective and productive at work, ultimately helping customers win.</p>
<h2 id="why-doc-as-code">Why Doc-as-Code?</h2>
<p>We have witnessed a sudden surge in the number of subject matter experts that are enthusiastic about contributing to documentation while our existing authoring tools failed to meet contributors’ requirements. Because our contributors span from developers to product managers and support teams, we felt it’s advantageous to integrate our authoring system into the developer workflow to enable smooth collaboration.</p>
<h2 id="the-journey-unstructured-to-structured-to-semi-structured">The Journey: Unstructured to Structured to Semi-Structured</h2>
<p>We have tried a bunch of different ways to handle public documentation over the years before embarking on the GitHub way. All the previous tried-and-tested systems have proved either restricted or ill-fitting for our requirements, be it a structured or unstructured tool.</p>
<p>Sysdig documentation was initialized as a bunch of <a href="https://support.zendesk.com/hc/en-us/articles/4408839258778">Zendesk</a> articles. As the product suits evolved and the proliferation of content became unmanageable, we required a content management system optimized for collaboration. Because Sysdig uses <a href="https://support.atlassian.com/confluence-cloud/docs/create-and-edit-content/">Confluence</a> for internal documentation, the next logical step was to switch to Confluence.</p>
<p>Confluence came up with its own challenges. The version we were using missed most of the enterprise features, including topic reuse, version control, and the facility to customize the pages according to Sysdig branding. At the time, both content development and documentation tooling had been managed entirely by the documentation team.</p>
<table>
<thead>
<tr>
<th>Confluence Advantages</th>
<th>Confluence Disadvantages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cost</td>
<td>Limited branding / customization options</td>
</tr>
<tr>
<td>Ease of use for authoring</td>
<td>Inability to reuse topics</td>
</tr>
<tr>
<td>Ease of contribution</td>
<td>Limited versioning/content management options</td>
</tr>
</tbody>
</table>
<p>In order to adopt a Sysdig look and feel for the documentation site, we arrived at a decision to jettison it for an Enterprise authoring and content management system with specialized support. And we chose Paligo.</p>
<p><a href="https://paligo.net/product/">Paligo</a>, an XML-based authoring & content management system, offered most of the functionalities for the Enterprise. However, it missed an integrated-hosting service with version control. We had to build a GitHub- and static site-based workflow for versioning and publishing, which implies we were, in part, already into the Doc-as-Code system. Besides, the XML-based contributor interface became a hurdle to contributors external to the documentation team. And subject matter experts started to build content repositories for experiment features in GitHub and pulling that content into XML-based Paligo became a nightmare. To streamline content creation and allow for broader team contributions, the switch was inevitable.</p>
<table>
<thead>
<tr>
<th>Paligo Advantages</th>
<th>Paligo Disdvantages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Topic reuse</td>
<td>Collaboration hurdles</td>
</tr>
<tr>
<td>XML-based authoring</td>
<td>Unfriendly branching Interface</td>
</tr>
<tr>
<td>Localization support</td>
<td>Unfriendly reviewer/contributor interface</td>
</tr>
<tr>
<td>Enterprise-level support from Paligo</td>
<td>No markdown support</td>
</tr>
<tr>
<td>Branching/staging</td>
<td>No hosting services</td>
</tr>
<tr>
<td>Enhanced search</td>
<td> </td>
</tr>
<tr>
<td>Content management</td>
<td> </td>
</tr>
</tbody>
</table>
<p>In short, if Zendesk articles worked well for the support organization, it was not fit for complete end-to-end product documentation. If Confluence worked very well for doc contributors, it was way too conventional to retain versions or follow Sysdig branding. No one system ever seemed to satisfy all our requirements.</p>
<h2 id="hackathon-effect">Hackathon Effect</h2>
<p>A Hackathon is a time-boxed event in which cross-functional teams work on creative ideas. Sysdig conducts a yearly Hackathon fest where employees can propose innovative ideas and collaborate with colleagues who they don’t otherwise get to work closely with.</p>
<p>The impossible becomes possible with the Sysdig Hackathon. Our team proposed the idea of porting the XML content in Paligo to the Doc-as-Code scheme using an innovative in-house tool.</p>
<p>As <a href="https://en.wikipedia.org/wiki/Parkinson's_law">Parkinson’s law</a> states, “work expands so as to fill the time available for its completion.” Thanks to the Hackathon, the effort concluded with the content having been ported to Github in markdown format and having an aesthetic Hugo-Docsy-based website live.</p>
<h3 id="conversion-tooling">Conversion Tooling</h3>
<p>Porting DocBook XML content in Paligo to Doc-as-Code-friendly markdown format required some level of automation, and the obvious choice for the conversion was <code class="language-plaintext highlighter-rouge">pandoc</code>. It is an open-source universal document converter that supports both DocBook and markdown. However, you cannot simply run a <code class="language-plaintext highlighter-rouge">pandoc</code> command and expect the XML to be converted into a desired form of markdown. Not all DocBook tags are easily convertible to markdown. There are many attributes that XML has and markdown does not, and on top of that, Paligo proprietary identifiers require different treatment.</p>
<p>Therefore, the focus of the Hackathon team was to refine the XML file prior to running the <code class="language-plaintext highlighter-rouge">pandoc</code> command, and post conversion, cleaning up the tags in the converted markdown files. Patching the XML file included, but was not limited to, replacing attributes with those that <code class="language-plaintext highlighter-rouge">pandoc</code> can identify. The post-conversion refinement dealt mostly with polishing how content is displayed on the website.</p>
<p>The result was a Python script to solve this problem and make the conversion automated.</p>
<h3 id="cicd-pipeline">CI/CD Pipeline</h3>
<p>We chose <a href="https://gohugo.io/">Hugo</a> static site generator with <a href="https://www.docsy.dev/">Docsy</a> theme for building the documentation website for its rich feature set. Hugo is faster, offers a rich feature set for expansion, and has an active community for support. Docsy offers features such as dark theme, RSS feed support, and swagger integration for APIs, which we plan to introduce to the site at some point. <a href="https://www.netlify.com/">Netlify</a> is faster to launch and easier to integrate with Github repository for hosting preview and production builds. The publishing flow has been designed in such a way that each Pull Request would generate a preview build so reviewers can see the content as it would appear on the website. This mechanism accelerated our documentation publishing pace without sacrificing quality.</p>
<p><img src="/images/sysdig/adopting-doc-as-code-01.png" alt="" /></p>
<h3 id="from-docs-as-code-to-docs-from-code">From Docs-as-Code to Docs-from-Code</h3>
<p>Our move to the docs-as-code scheme of things has not only enabled us to automate doc publishing, but also equipped us to automate doc development. Gaps in documentation mostly occur when modification of source code and documentation are not in sync. Unfortunately, this is typical when different people contribute to the code under a time crunch in project cycles.</p>
<p>The “doc-from-code” method that we devised tries to solve this case.</p>
<p>A part of our documentation is automated in such a way that content is generated by parsing the source code and configuration files in the projects. We developed a set of templates to parse the source code and render the content in the doc. The template is run periodically or when a new release is published. This process also generates an updated version of the docs and creates an automated pull request ready to be reviewed and published by the docs team. This ensures that documentation is always updated, no matter who contributes to the source code of our applications. Also, parsing code to generate docs saves time and resources, as well as makes our docs coherent in content and formatting.</p>
<p>Finally, one of the latest Hackathon projects iterated over this workflow to handle automating tooltip and documentation creation for the metric dictionary. Automating metric dictionary creation is expected to drive cross-functional teams to collaborate closely on improving metrics definitions and thereby eliminate manual errors and frictions that might otherwise be introduced to the path.</p>
<h2 id="conclusion">Conclusion</h2>
<p>In the new scheme of things, Sysdig documentation is stored and managed in GitHub alongside source code. The current authoring environment, built by gluing together SaaS products and OSS components, is collaboratively maintained by documentation and development teams. As a result, we decamped a licensed structured authoring tool that presented barriers to easy doc contributions.</p>
<table>
<thead>
<tr>
<th>Docs-as-Code Advantages</th>
<th>Docs-as-Code Disadvantages</th>
</tr>
</thead>
<tbody>
<tr>
<td>Tighter collaboration with SMEs</td>
<td>We are still exploring and experimenting and will be back with our learnings!</td>
</tr>
<tr>
<td>Easy integration with Sysdig repositories</td>
<td> </td>
</tr>
<tr>
<td>Easier versioning branching for releases</td>
<td> </td>
</tr>
<tr>
<td>Staging / Preview builds</td>
<td> </td>
</tr>
<tr>
<td>Enhanced search</td>
<td> </td>
</tr>
<tr>
<td>Dark mode</td>
<td> </td>
</tr>
<tr>
<td>RSS feed</td>
<td> </td>
</tr>
<tr>
<td>In-house doc infrastructure</td>
<td> </td>
</tr>
</tbody>
</table>
<p>The switch has witnessed measurable success within a month of rolling out into production: the number of contributors has increased 15 times; the doc deployment time has been reduced to seconds. By eliminating manual review processes and introducing an automated web-based staging environment, doc publishing has been expedited. Docs-as-code also has enabled us to automate repetitive activities associated with documentation development. Above all, we have achieved shared ownership of developing and delivering quality content to help our customers succeed.</p>
<p><a href="https://www.docslikecode.com/articles/sysdig-adopting-docs-as-code/">Adopting Docs-as-Code: From Hackathon to Production</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on July 11, 2022.</p>
https://www.docslikecode.com/articles/setting-up-techdocs-on-backstage2021-02-14T00:00:00+00:002021-02-14T00:00:00+00:00Padraig O'Brienhttps://www.docslikecode.com
<p>TechDocs is Spotify’s homegrown docs-like-code solution built directly into Backstage. <a href="https://github.com/backstage/backstage">Backstage</a> gives teams one front-end view for all their infrastructure tools, like Google Cloud Platform, Cloud Bigtable, CI pipelines, TensorFlow Extended, and others, all in a consistent, easy-to-use interface, or portal. It’s open source software released by Spotify.</p>
<p>With TechDocs built into Backstage, all the engineers write their documentation in Markdown files which live together with their code. You can read more about their docs-as-code story in <a href="https://www.docslikecode.com/articles/ten-tips-maintaining-long-term-docs-like-code/">this article</a>. In this post we will walk you through how to setup Backstage and Techdocs.</p>
<p><strong>Table of contents</strong></p>
<ul>
<li>Introduction</li>
<li>Basic concepts and structure of Backstage and TechDocs</li>
<li>Install Backstage</li>
<li>Setup TechDocs</li>
<li>Create and publish documentation</li>
<li>Publish to cloud storage (example)</li>
<li>Recap and summary</li>
</ul>
<h2 id="introduction">Introduction</h2>
<p>Backstage is a platform for building developer portals, giving one view into developer tools.</p>
<p>Its main benefit is allowing you to ship high quality code fast thanks to consistent views of your tools and infrastructure.</p>
<p>The features you get out of the box are:</p>
<ul>
<li>Service catalog</li>
<li>Software templates</li>
<li>Plugins which allow you to extend Backstage functionality</li>
<li>TechDocs, which is the focus of this post</li>
</ul>
<p>These features allow you to create standards and best practices across teams. It increases the speed of development. It creates a good developer experience for everyone who uses it. You centralize all your tools and information in one place.</p>
<p>In this post I will take you through the basic concepts and structure of Backstage and TechDocs, an installation of Backstage including the setup of TechDocs, creating and publishing documentation, all on a local machine on MacOS.</p>
<h2 id="basic-concepts-and-structures-of-backstage-and-techdocs">Basic concepts and structures of Backstage and TechDocs</h2>
<p>The focus of this article is TechDocs, so I will go through the main features at a high level.</p>
<ul>
<li>Service catalog - It keeps track of ownership and metadata for all the software in your ecosystem. Backstage does this by putting metadata in YAML files stored together with your code. You process these files and then you can visualise the catalog in Backstage. This catalog enables your teams to manage and maintain the software they own, making the software discoverable.</li>
<li>Software templates - This feature allows you to create templates or skeletons of code. These templates are published to GitHub.</li>
<li>Plugins - Allow you to integrate third party tools or any kind of infrastructure into Backstage. They are open source and you can view a list <a href="https://backstage.io/plugins">here</a>.</li>
<li>Techdocs - Yay, finally, why we are here. Techdocs is Spotify’s homegrown docs like code solution. It allows the user to store documentation near the relevant code, thus allowing the docs to be easily discovered and maintained.</li>
</ul>
<p>When you deploy Backstage with Techdocs enabled you get a basic out of the box experience.</p>
<p>At its core, TechDocs is an MKDocs plugin with other MkDocs plugins and Python Markdown extensions which allows it to standardize the configuration of MkDocs used for TechDocs.</p>
<p>You can see the source code for TechDocs <a href="https://github.com/backstage/mkdocs-TechDocs-core">here</a>.</p>
<p>The other moving parts are:</p>
<ul>
<li>The TechDocs container which can be found on DockerHub at https://hub.docker.com/r/spotify/techdocs, which builds static content through MKDocs.</li>
<li>The Techdocs backend plugin which is the backend part of the TechDocs plugin.</li>
<li>The Techdocs CLI, a handy command line tool for managing TechDocs sites in Backstage.</li>
<li>The Techdocs reader, it fetches remotes pages, runs “transforms” against them, and renders them in a shadow DOM.</li>
<li>The Transforms API takes in parameters from the reader component and returns a function which gets passed the DOM of the fetched page.</li>
</ul>
<p><strong>Architecture</strong></p>
<p><img src="/images/techdocs/backstage-techdocs-architecture.png" alt="Architecture diagram" /></p>
<p>When you open a TechDocs site, a request is made. The TechDocs reader calls the TechDocs-backend with the entity id and the path of the current page. The response contains the static content. The static content contains HTML and CSS, and any JavaScript is removed for security reasons.</p>
<p>Transforms are then applied which modify the generated static HTML files for a number of reasons like removing certain headers and so on.</p>
<p>For the following instructions, since we are using a local install for demonstration and trial, we will use the local file storage, but in production you would use cloud storage like S3.</p>
<h2 id="install-backstage">Install Backstage</h2>
<blockquote>
<p>If you have any difficulty with the installation, you can <a href="https://github.com/backstage/backstage/issues">log an Issue in the Backstage repository</a>.</p>
</blockquote>
<h3 id="prerequisites">Prerequisites</h3>
<ul>
<li>
<p>Mac running MacOS</p>
</li>
<li>
<p>Node Version Manager (nvm) so that you can ensure you’re using Node version 14. Run: <code class="language-plaintext highlighter-rouge">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash</code> or <code class="language-plaintext highlighter-rouge">curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | zsh</code> on MacOS Catalina and newer.</p>
</li>
<li>
<p>Node version 14.x (Cannot use Node version 15.x) (You can use <code class="language-plaintext highlighter-rouge">brew install node</code> to install on MacOS if needed.) Run <code class="language-plaintext highlighter-rouge">nvm use --lts</code> so that you can run Node version 14.15.5 for this demo.</p>
</li>
<li>
<p>Yarn (Use <code class="language-plaintext highlighter-rouge">brew install yarn</code> for this demo.)</p>
</li>
</ul>
<p>If you already have Backstage installed, then you skip this “create-app” step. First, create the initial app in any directory you choose:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">npx</span> <span class="p">@</span><span class="nd">backstage</span><span class="sr">/create-ap</span><span class="err">p
</span></code></pre></div></div>
<p>This will take a few minutes.</p>
<p>You are asked some questions on setup. The recommendation for this local tutorial is to go with SQLLite by using the down arrow when prompted.</p>
<p><img src="/images/techdocs/create-app.png" alt="npx install" /></p>
<p>If successful you see this message:</p>
<p><img src="/images/techdocs/01.png" alt="successful" /></p>
<p>Change into your created app’s directory, the name you used for the app. In this example the name is <code class="language-plaintext highlighter-rouge">infraportal</code>:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd infraportal
</code></pre></div></div>
<p>Then run:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">yarn</span> <span class="nx">workspace</span> <span class="nx">backend</span> <span class="nx">start</span>
</code></pre></div></div>
<p><img src="/images/techdocs/02.png" alt="yarn workspace" /></p>
<p>Open a new terminal window and change directories to the <code class="language-plaintext highlighter-rouge">infraportal</code> where you created the app.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>cd ~/src/backstage/infraportal
</code></pre></div></div>
<p>Then start the app with this command:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">yarn</span> <span class="nx">run</span> <span class="nx">start</span>
</code></pre></div></div>
<p><img src="/images/techdocs/03.png" alt="yarn start" /></p>
<p>If successful, a browser window opens and you should be presented with a window.</p>
<p><img src="/images/techdocs/04.png" alt="successful register" /></p>
<p>Well done, you have successfully installed Backstage on your local machine.</p>
<h2 id="setup-techdocs">Setup TechDocs</h2>
<p>Historically you had to manually add Techdocs, but now the latest version of <code class="language-plaintext highlighter-rouge">create-app</code> bundles TechDocs.</p>
<p>To verify this setup, you should be able to see entries for the plugin <code class="language-plaintext highlighter-rouge">'@backstage/plugin-TechDocs';</code> in the following files:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">packages</span><span class="o">/</span><span class="nx">app</span><span class="o">/</span><span class="nx">src</span><span class="o">/</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">ts</span>
<span class="nx">packages</span><span class="o">/</span><span class="nx">app</span><span class="o">/</span><span class="nx">src</span><span class="o">/</span><span class="nx">App</span><span class="p">.</span><span class="nx">tsx</span>
</code></pre></div></div>
<h2 id="creating-and-publishing-techdocs">Creating and publishing TechDocs</h2>
<p>To create docs manually from scratch, click on Create component:</p>
<p><img src="/images/techdocs/05.png" alt="manuall" /></p>
<p>From here choose the Documentation template.</p>
<p><img src="/images/techdocs/06.png" alt="template" /></p>
<p>Fill out a Name and Description.</p>
<p><img src="/images/techdocs/07.png" alt="Name Desc" /></p>
<p>Have a GitHub org or owner and a GitHub repo ready to use for your docs. Have a <a href="https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token">GitHub token created</a> and available in your environment as <code class="language-plaintext highlighter-rouge">GITHUB_TOKEN</code>. Type in the GitHub owner and the GitHub repo you want to use. Make sure there is no GitHub repo that exists with the same name or the Templater will fail.</p>
<p><img src="/images/techdocs/08.png" alt="owner" /></p>
<p>Once you click on create you will be presented with a Create component status popup.</p>
<p><img src="/images/techdocs/09.png" alt="create component" /></p>
<p>Once the repository has been published to GitHub, the Create component status popup will show green like below.</p>
<p><img src="/images/techdocs/10.png" alt="popup" /></p>
<p>You will be able to navigate to the docs.</p>
<p><img src="/images/techdocs/11.png" alt="navigate" /></p>
<p>If this is the first time you are loading the docs, you could receive this message while it converts from Markdown to HTML.</p>
<p><img src="/images/techdocs/12.png" alt="loading" /></p>
<p>Here is a screenshot of what you will be presented with.</p>
<p><img src="/images/techdocs/13.png" alt="results" /></p>
<p>You now have TechDocs up and running on your machine. Well done. If you want to view the files and work on them locally they are located at the following location on your machine:</p>
<div class="language-jsx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">backstage</span><span class="o">/</span><span class="nx">node_modules</span><span class="o">/</span><span class="p">@</span><span class="nd">backstage</span><span class="sr">/plugin-TechDocs-backend/</span><span class="kd">static</span><span class="sr">/docs/</span><span class="k">default</span><span class="sr">/Component/</span>
</code></pre></div></div>
<p>Your workflow would be to work on the files, preview locally, then commit your changes and send in pull requests, using your team’s Git workflows.</p>
<h2 id="publish-to-cloud-storage">Publish to cloud storage</h2>
<p>The recommended setup is to place the output on to cloud storage such as S3, and not on the local machine, so let’s look at that.</p>
<blockquote>
<p>Note: This section is just an overview, and not a full tutorial, because there are a lot of prerequisites for setting up cloud storage. If you’re interested, read the AWS S3 documentation about <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/create-bucket-overview.html">Creating a bucket</a> and the <a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/UsingBucket.html">Buckets overview</a>.</p>
</blockquote>
<p><img src="/images/techdocs/14.png" alt="cloud" /></p>
<p>When you startup Backstage you should see this message in the logs to confirm you are using cloud storage:</p>
<p><img src="/images/techdocs/15.png" alt="registered" /></p>
<p>You will also see the content in the S3 bucket.</p>
<p><img src="/images/techdocs/16.png" alt="s3" /></p>
<h2 id="recap-and-summary">Recap and summary</h2>
<p>In summary, we went through an introduction on Backstage, TechDocs, and how to publish TechDocs locally. We took a look at the cloud storage option with some screenshots showing S3. To learn more about Backstage I would recommend visiting <a href="https://backstage.io">https://backstage.io</a> or if you want to learn more about TechDocs then <a href="https://backstage.io/docs/features/techdocs/techdocs-overview">https://backstage.io/docs/features/techdocs/techdocs-overview</a> offers a great overview.</p>
<p>You can also read about the gains the team at Spotify has seen since using TechDocs for all their documentation in <a href="https://www.docslikecode.com/articles/ten-tips-maintaining-long-term-docs-like-code/">Ten tips for maintaining a long-term relationship with docs like code</a>. TechDocs has a really nice <a href="https://github.com/orgs/backstage/projects/1#card-54927264">project board in GitHub,</a> so if you’re interested in working on it yourself, take a look.</p>
<p>If you like the idea of Backstage but don’t want the inconvenience of managing Backstage yourself, then check out <a href="https://roadie.io">https://roadie.io</a>. Thanks for taking a look at this tutorial and happy documenting!</p>
<p><a href="https://www.docslikecode.com/articles/setting-up-techdocs-on-backstage/">Setting up Techdocs on Backstage</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on February 14, 2021.</p>
https://www.docslikecode.com/articles/survey-results-docs-like-code2021-01-09T00:00:00+00:002021-01-09T00:00:00+00:00Anne Gentlehttps://www.docslikecode.com
<p>I asked three questions in a survey emailed to my mailing list and got more than 30 responses. Thanks to everyone who took the time to share their stories and respond. Here are the three questions:</p>
<ul>
<li>
<p>Question 1: When you talk to your leaders about docs-as-code, can they describe the benefits as well as the difficulties?</p>
</li>
<li>
<p>Question 2: How do you onboard people who are new to your docs tools and processes?</p>
</li>
<li>
<p>Question 3: What tips or discussions (from any source) was most helpful to you when learning docs-as-code techniques?</p>
</li>
</ul>
<p>Docs-as-code processes are still new in the field and it seems many of the responses are split, with no overwhelming patterns in any single area. Let’s look into the data and charts for the first two questions.</p>
<h2 id="question-1-when-you-talk-to-your-leaders-about-docs-as-code-can-they-describe-the-benefits-as-well-as-the-difficulties">Question 1: When you talk to your leaders about docs-as-code, can they describe the benefits as well as the difficulties?</h2>
<p><img src="/images/survey-charts/leadership-docs-tools.png" alt="" /></p>
<p><strong>Legend</strong></p>
<p><strong>26.8</strong>% Yes, my leader started our processes and makes it possible for us to use our current tools and processes.</p>
<p><strong>19.5</strong>% Yes, my leader can provide their leadership complete justification for our choices.</p>
<p><strong>19.5</strong>% No, I work in an environment where my tool selection does not need justification from a management chain.</p>
<p><strong>19.5</strong>% No, my leadership chain doesn’t really know what I do or why I use certain tools.</p>
<p><strong>14.6</strong>% It depends on which leader I’m talking to.</p>
<p>In a way, nearly all the responses could be viewed as “leadership either supports the selection does not get in the way of tool selection.” For about two-thirds of the responses, either leadership can justify, started the processes, or isn’t a deciding factor.</p>
<p>Looking at the number of lone writer responses in the next question, this indicator makes sense as five of thirty-five respondents noted that they were the only writer in the organization, which would make up 14% of all responses. Let’s take a look.</p>
<h2 id="question-2-how-do-you-onboard-people-who-are-new-to-your-docs-tools-and-processes">Question 2: How do you onboard people who are new to your docs tools and processes?</h2>
<p><img src="/images/survey-charts/how-onboard-docs.png" alt="" /></p>
<p><strong>Legend</strong></p>
<p><strong>14.6</strong>% Internal write-up only</p>
<p><strong>20.2</strong>% Meeting only</p>
<p><strong>1.1</strong>% Pre-built environment only</p>
<p><strong>5.6</strong>% Lone writer</p>
<p><strong>23.6</strong>% Internal write up and meeting</p>
<p><strong>34.8</strong>% Internal write-up, meeting, and pre-built environment</p>
<p>My favorite answer to this question was one I hadn’t considered, where the person is a lone writer, but works with the devs to get the docs working in the source code repo. It’s along the lines of “It’s complicated.”</p>
<blockquote>
<p>“Nothing, I’m the only person working on docs. The developers required documentation to work with our first attempt because we tried to use tool stacks that crossed different departments between authoring and publishing. Extensive process documentation was required in order for devs to figure out how the docs were to fit together despite the fact that we used markdown and the docs were in the source code repo. We switched tracks when the pain of the “throw it over the wall approach got too big. At which point we started a whole new docs site on a JAM stack platform. But still… Baby-steps.”</p>
</blockquote>
<h2 id="question-3-what-tips-or-discussions-from-any-source-was-most-helpful-to-you-when-learning-docs-as-code-techniques">Question 3: What tips or discussions (from any source) was most helpful to you when learning docs-as-code techniques?</h2>
<p>For question three, I wanted to share any nuggets found in the answers here on the Docs Like Code site, since the goal for this site is to learn these techniques together and share our stories. Here are some highlights.</p>
<blockquote>
<p>“Write the Docs community. Hustling the hard streets of Google search results. Your book!”</p>
</blockquote>
<blockquote>
<p>“Trail and Error - lots of searching. Reliance on internal Dev Ops”</p>
</blockquote>
<blockquote>
<p>“Familiarity with Git was key - I had already used Git on a smaller scale for personal projects and that helped me become comfortable when I had to collaborate with other writers/devs. And even then I still had to constantly refer to Git-related resources online to make sure I wasn’t messing anything up.”</p>
</blockquote>
<blockquote>
<p>“Your Docs as Code book was helpful, for certain. Recently, Frank Miller and Rik Page had two broad discussions about using GIT in lieu of a cCMS (see Git Happens <a href="https://vimeo.com/431452486">part 1</a> and <a href="https://vimeo.com/449217243">part 2</a>). The main fear I have is different technical aptitudes and willingness to learn of the writers with whom I work. Some will adapt to GIT easily, while others will struggle mightily.”</p>
</blockquote>
<blockquote>
<p>“It’s still writing. If you don’t have documentation as business goal with the processes to produce it - e.g. customer expectation to receive docs with a new release so docs as part of Definition of Done - then docs in code won’t help.
Also, engineers won’t write unless they’re told to. You need a push down from leadership. Don’t try to grassroots it.”</p>
</blockquote>
<blockquote>
<p>“show people that the browser<>Git edit flow is ok, but IDE<>Git<>Browser is far better… show people how much support a good IDE plugin can give (asciidoctor plugin for IntelliJ has so many great features)”</p>
</blockquote>
<blockquote>
<p>“We use GitHub already so the argument to switch was easy. When I told the dev teams they didn’t need to use different tools, they were sold. I did, however, make a big mistake early on in the transition. I failed to point out that any non-code related docs (team/training content) should be separate from the code-related docs (readme.md) because not everyone had GitHub work accounts. As a result, non-dev employees couldn’t access anything. That’s not a result of the technique but bad planning on my part. Other than that, it’s been a lean and efficient methodology for how we document our dev projects.”</p>
</blockquote>
<blockquote>
<p>“Putting the documentation in source code where the developers can get to it. Attempting to docs-as-code with 2 stacks requiring a conversion from markdown to HTML fragments ingested by a little known CMS (MODX) as the published content was a poorly thought out approach. I tried to warn the guys about this - especially since we didn’t have a way to duplicate the nested CMS structure required on the publishing end… But we lived with it for a year before it became painfully obvious that another solution was required.”</p>
</blockquote>
<blockquote>
<p>“I studied your shared extent extensively when I was starting out. Other courses include Peter Gruenbaum’s set on Udemy, Tom Johnson’s blog, and chats in the Write the Docs Slack channel.”</p>
</blockquote>
<blockquote>
<p>“Sarah Parson’s Write the Docs presentation on static site generators and Tom Johnson’s explanation of his Documentation Jekyll theme.”</p>
</blockquote>
<p>This is not a section simply to point to the <a href="https://docslikecode.com/book/">Docs Like Code book</a> as a resource, rather, it’s to show that having additional resources including people you can ask questions is super valuable when learning how to treat docs like code. I’m grateful to the Write the Docs community and people who are also writing their experiences here and on other sites so we can all learn together. Thanks to everyone who shared their experiences and hard-earned wisdom!</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/survey-results-docs-like-code/">Survey results for learning and teaching docs-like-code techniques</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on January 09, 2021.</p>
https://www.docslikecode.com/articles/ten-tips-maintaining-long-term-docs-like-code2020-11-06T00:00:00+00:002020-11-06T00:00:00+00:00Gary Niemenhttps://www.docslikecode.com
<p>I remember about two years ago sitting here watching a Write the Docs video. Well, not precisely “here” because we sat in offices in those days and in 2020 I’m in my home office. I was watching, wide-eyed and a bit confused, a video of <a href="https://youtu.be/EnB8GtPuauw">Riona MacNamara’s talk from Write the Docs 2015</a>. In the talk, Riona described how she and another technical writer used a docs-like-code approach to change Google engineering culture around technical documentation.</p>
<p>I remember seeing this adoption curve and saying to myself: We need to do this. I want that curve.</p>
<p><img src="/images/spotify/adoption1.png" alt="running total: projects & authors from Documentation, Disrupted " /></p>
<p>And just a few months later, we had built and released TechDocs, Spotify’s docs-like-code solution for internal technical documentation. And a few months after that, we had the curve that I had longed for. Nice gradient, eh?</p>
<p><img src="/images/spotify/adoption2.png" alt="Adoption Stats" /></p>
<p>If you haven’t heard of it, Spotify is a digital music, podcast, and video streaming service providing access to content from artists around the world. We were fortunate in that there were several synchronous moments that helped us, but overall, we moved fast because we were able to make use of preexisting infrastructure, such as <a href="https://backstage.io/">Backstage</a> (our homegrown and now open sourced developer portal) and Tingle, Spotify’s CI/CD tool. We also made use of the open source static site generator, <a href="https://www.mkdocs.org/">MkDocs</a>.</p>
<p>In just two short years, writing docs in Markdown in our enterprise version of GitHub has become standard practice. We have over 3,000 doc sites from across the organisation, all showing up and searchable in Backstage. And most of the feedback we get from engineers is positive with the odd request for a small tweak or improvement.</p>
<p><img src="/images/spotify/techdocs.png" alt="TechDocs Documentation screenshot" /></p>
<p>Time to put our feet up, right?</p>
<p>Not quite. We have outlasted the honeymoon period, moved past the one-year anniversary, and now suddenly find ourselves in the territory of a long-term relationship. Now is definitely not the time to take anything for granted.</p>
<p>So, with that in mind: here are 10 tips for keeping your long-term relationship with docs like code thriving:</p>
<h2 id="1-keep-fiercely-optimizing-for-engineers">1. Keep fiercely optimizing for engineers</h2>
<p>One of the keys to our success has been our commitment to fiercely optimize for engineers by creating a documentation infrastructure fully aligned with the existing engineering workflow. Well, that’s what docs like code is all about, right? But one can easily be swayed.</p>
<p>Can we use Jira instead of GitHub to report issues? Can we use a Google Doc and embed it into TechDocs? Can we use Lucid Charts for diagrams instead of PlantUML? Is it possible to have our source in Markdown in GitHub and get it to show up in Confluence?</p>
<p>Some of these requests were from non-engineers and some from engineers. Whatever the case, our stance is always the same: Continue to optimize for engineers and the engineering workflow.</p>
<h2 id="2-sanctify-the-frictionless-experience">2. Sanctify the frictionless experience</h2>
<p>Another key factor for us was making sure that the workflow from authoring in Markdown to a nice-looking website in Backstage is a frictionless experience. Everything just works.</p>
<p>We have had requests to add metadata to .yaml files, break the build if doc sites fail, and a bunch of other workflow-breaking extras — but each time we have resisted and prioritized the frictionless experience.</p>
<p>We have even pushed the frictionless experience further by including docs setup when software components are created in Backstage and removing various MkDocs configuration requirements.</p>
<h2 id="3-have-an-opinionated-position-and-hold-onto-it">3. Have an opinionated position, and hold onto it</h2>
<p>Very early on, we boldly said to Spotify’s tech community: <em>TechDocs is now the one way to produce documentation, and Backstage is now the one place to find and consume it</em>. Then we ducked. But no missiles came our way, and we got it through. I think the organisation was ripe for this standardisation, having become totally fed up with documentation being distributed across so many places, such as Confluence, Google Docs, README files, GitHub Pages, and various websites.</p>
<p>What I would say is this: Hold onto the opinionated position. It’s one of the keys to success and should be a kind of guiding light as you move forward with your docs-like-code solution.</p>
<h2 id="4-beware-of-second-order-effects">4. Beware of second-order effects</h2>
<p>I have been thinking about second-order effects a lot recently. We make what we think is a good decision and then hey-ho, a few days or a week later, negative consequences of that decision start to emerge. What do we do? Do we reverse the decision? Do we tweak it? Do we try to address the new negative consequences? Or do we carry on regardless? Working with product — as in life — it’s important to consider second-, third-, and nth-order effects. Here is a <a href="https://fs.blog/2016/04/second-order-thinking/">great piece on the topic</a>. (Aside: I wonder to myself sometimes if the whole history of humankind is not an nth-order effect.)</p>
<p>We’ve fallen victim to second-order effects a number of times. Here’s one:</p>
<p>We adjusted the reading width in Backstage to fall in line with accessibility guidelines. What could go wrong there? Plenty, it turns out. The reading width becomes too narrow when the font is small. Wide tables need a scroll bar, and that makes them less readable. And the narrower reading frame looks weird on a large computer screen. Support questions rolled in and…rolled in — taking up a great chunk of our engineers’ time. From peace, we had created chaos.</p>
<p>Beware of second-order effects.</p>
<h2 id="5-techdocs-is-great-but-please-fix-search">5. TechDocs is great, but please fix search</h2>
<p>The first big argument after the honeymoon period was about finding stuff. To paraphrase two and a half pages of feedback: “TechDocs is great, but please fix search.”</p>
<p>I get this. It is all very well and good having all of your technical documentation in one place, but if you can’t find it — well, what’s the use? The opposite is also true, by the way. If you have a great search engine but what you find is out of date or of low quality, then again — what’s the use? So, we listened to our users and are now working to improve search success.</p>
<h2 id="6-dont-rely-on-vanity-metrics-establish-actionable-metrics-and-watch-them-instead">6. Don’t rely on vanity metrics; establish actionable metrics and watch them instead</h2>
<p>In the early days, we were all about adoption. “Hey Gary, we are up to 200 sites.” “Hey Emma, it’s 500 sites now.” “We are up to 1,000 sites, let’s celebrate!” We just wanted that nice upward slope. But as time went on, we started to see that really, the number of doc sites was little more than a vanity metric. So we started to think more deeply about which metrics would be more useful to track. This is still a work in progress, but our top metrics at the moment are:</p>
<ul>
<li>Total visits</li>
<li>Number of actual doc updates</li>
<li>Issues and open PRs around docs</li>
<li>Successful searches</li>
</ul>
<p>We also send out a short survey every six months to gauge if TechDocs is helping engineers get unstuck faster, check whether we are moving people away from other documentation platforms, and fish for general feedback.</p>
<h2 id="7-use-the-feedback-loop-to-maintain-doc-quality">7. Use the feedback loop to maintain doc quality</h2>
<p>Before we introduced our docs-like-code solution TechDocs, an often-heard complaint from engineers was: <em>I don’t know where to find information, and if I do find it, I don’t know if it is up to date</em>. With the introduction of TechDocs, this complaint vanished. There was now one place to find information. Plus, teams migrated their existing content onto the platform and started creating new content on it, so there was a sense that now, not only was everything in one place, but everything was up to date as well. Nirvana.</p>
<p>But (yes, of course, there is a but), as time went on, the “I don’t know if it is up to date,” complaint began to reemerge. And, to be honest, we kind of knew this was going to happen. We don’t have technical writers watching over the documentation; that simply doesn’t scale. So we knew we needed some other way to keep the doc quality up.</p>
<p>The way we do this is to try and nurture a thriving community of technical documentation producers, contributors, and consumers. And we do this by building up a free-flowing feedback loop. In other words, we make it easy for consumers of documentation to contribute or give feedback. We then make sure that the contributions or feedback gets to the right teams and that those teams are, in some way, incentivized to make the suggested updates. Then, to complete the loop, the ones who gave the feedback are notified that it has been addressed.</p>
<h2 id="8-give-teams-data-on-their-doc-sites">8. Give teams data on their doc sites</h2>
<p>Just as it is important that teams know what software they own, it is equally important that they know what documentation they own. Giving our teams this functionality was a key factor in making the long-term relationship work (kind of a one-year anniversary gift). On a nice-looking dashboard, teams can see which doc sites they own or part own, when they were last updated, and number of GitHub Issues per doc site. We have heaps of ideas for more data we could add — just to keep the relationship fresh, of course.</p>
<h2 id="9-productify-your-tech-writer-knowledge-and-experience">9. Productify your tech-writer knowledge and experience</h2>
<p>Early on, we made the bold decision to move our tech writers up the stack. In other words: build a team of tech writers and engineers, and build a tool to scale and solve technical documentation at Spotify. The tech writers would instill their knowledge and experience into the product. But they wouldn’t do any actual technical writing. And that’s basically what we have done.</p>
<p>We rely on crowdsourcing and the feedback loop (as described above) to keep overall doc quality high. Our tech writers don’t review technical documentation.</p>
<p>However, engineering teams do get word that we have tech writers stashed away on our team, and so we do get asked to help out with plenty of technical writing assignments. It is hard to say no sometimes, but overall we have managed to stick to our initial strategy:</p>
<p>What we do offer is:</p>
<ul>
<li>A one-hour introduction to technical writing at Spotify.</li>
<li>A one-hour “consultancy” meeting with the team.</li>
<li>A support channel for smaller questions.</li>
<li>Document templates.</li>
<li>A technical writing handbook that includes a style guide.</li>
</ul>
<p>We believe for a company the size of Spotify, this approach is the only way to scale quality technical documentation.</p>
<h2 id="10-commit-to-docs-like-code-and-keep-committing">10. Commit to docs like code and keep committing</h2>
<p>At Spotify, we have this key onboarding documentation called Golden Path tutorials. You can read about them here: <a href="https://engineering.atspotify.com/2020/08/17/how-we-use-golden-paths-to-solve-fragmentation-in-our-software-ecosystem/">How we use Golden Paths to solve fragmentation in our software ecosystem</a>. They present a great challenge to a docs-like-code solution because they are large, owned by multiple teams, and have many dependencies. In addition, we have one tutorial for each engineering discipline (for example, backend, data, web, etc.) and it’s crucial that the various tutorials play well together.</p>
<p>These tutorials used to be in Google Docs and people used to very much appreciate this format in particular the strong commenting features. We could have easily opted to keep the Golden Path tutorials in Google Docs, but we had committed to docs like code and we wanted to go all in. I remember our product manager at the time saying something like: If we can make this work for the Golden Path tutorials, it will help us solve for all other technical documentation at Spotify.</p>
<p>So we implemented the tutorials in TechDocs, use the <a href="https://docs.github.com/en/free-pro-team@latest/github/creating-cloning-and-archiving-repositories/about-code-owners">CODEOWNERS</a> file to keep track of ownership, and set up a special GitHub bot to handle notifications when GitHub Issues are raised. We are also starting to take it even further by exploring ways that we can use tooling to help teams keep track of the documentation dependencies found in the tutorials.</p>
<hr />
<p>So that’s about it. There’s your long-term relationship advice. Not bad for a bunch of techies eh?</p>
<p>One last note to let you know that <strong>we have now open sourced TechDocs</strong>. Let’s take TechDocs to the next level together. Everything you need to know, you’ll find in the blog post <a href="https://backstage.io/blog/2020/09/08/announcing-tech-docs">Announcing TechDocs: Spotify’s docs-like-code plugin for Backstage</a>.</p>
<h3 id="resources">Resources</h3>
<ul>
<li><a href="https://backstage.io/docs/features/techdocs/techdocs-overview">TechDocs Documentation</a></li>
<li><a href="https://github.com/backstage/backstage/tree/master/plugins/techdocs">Frontend code for TechDocs</a></li>
<li><a href="https://github.com/backstage/backstage/tree/master/plugins/techdocs-backend">Backend code for TechDocs</a></li>
<li>Tools for TechDocs: <a href="https://github.com/backstage/techdocs-cli">techdocs-cli</a> and <a href="https://github.com/backstage/techdocs-container">techdocs-container</a></li>
<li><a href="https://www.mkdocs.org/">MkDocs</a>, a static site generator</li>
<li><a href="https://www.markdownguide.org/">Markdown Guide</a></li>
<li><a href="https://backstage.io">Backstage</a>, an open platform for building developer portals</li>
<li><a href="https://github.com/backstage/backstage">github.com/backstage</a></li>
<li><a href="https://www.linkedin.com/posts/garyniemen_how-we-are-solving-internal-technical-documentation-activity-6646078605594030080-4L31">DevRelCon London, December 2019: Gary Niemen, The Hero’s Journey: How we are solving internal technical documentation at Spotify</a></li>
</ul>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/ten-tips-maintaining-long-term-docs-like-code/">Ten tips for maintaining a long-term relationship with docs like code</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on November 06, 2020.</p>
https://www.docslikecode.com/articles/platformos-4of42020-02-26T00:00:00+00:002020-02-26T00:00:00+00:00Diána Lakatoshttps://www.docslikecode.com
<p>In this article series we describe the process of building our <a href="https://www.platformos.com/blog/post/platformos-developer-portal-wins-uk-technical-communication-award">award-winning</a> developer documentation site from discovery to development, with in-depth insights into our approach, decisions, plans, and technical implementation.</p>
<ul>
<li><a href="/articles/platformos-1of4">Part 1: Information Architecture</a></li>
<li><a href="/articles/platformos-2of4">Part 2: Content Production and Layouts</a></li>
<li><a href="/articles/platformos-3of4">Part 3: Community</a></li>
</ul>
<p>Welcome to part 4, where we take a look under the hood, discuss the technologies we used, how we built our auto-generated API Reference, and how we use GitHub for our docs as code workflow and more.</p>
<h2 id="platformos-instance">platformOS Instance</h2>
<p>When developing a platformOS site or app, the process starts with setting up Instances. Instances have a URL, and they represent different development environments, like staging or production. For our own sites, like our documentation, we spin up the Instance and work in our codebase directly, but you can build a platformOS site using various CMS solutions built on platformOS (e.g. <a href="https://www.siteglide.com">Siteglide</a> or <a href="https://www.insites.io">Insites</a>) if you don’t want to fiddle with code.</p>
<p>Our documentation site has a staging instance for development and testing and a production Instance — the live site if all tests are green. It works with continuous integration and continuous deployment: it automatically runs tests, deploys to staging and then to production. Once done, it sends us a Slack notification. To support a small footprint deployment process, we use an asynchronous event-driven JavaScript runtime, Node.js.</p>
<p>Our codebase is <a href="https://github.com/mdyd-dev/nearme-documentation">on GitHub</a>. Besides standard web technologies like HTML, CSS, JavaScript (including JSON and AJAX), we use a couple of languages like YAML, Liquid, and GraphQL in our code. </p>
<h2 id="pages-and-layouts">Pages and layouts</h2>
<p>Documentation topics and other content like our Style Guide or Contributor Guide are Liquid pages, and the structure of pages is described in layouts. Pages have conditional sections, where you can decide what will be auto-generated for that particular page by setting specific flags in page metadata.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>metadata:
title: Contact
description: Send us a message, and we will get back to you as soon as possible.
questions: false
feedback: false
toc: true
breadcrumbs: false
</code></pre></div></div>
<ul>
<li>questions: questions section on the bottom with contact us button - default: true</li>
<li>feedback: block on the bottom of the page allowing readers to leave feedback - default: true</li>
<li>toc: table of contents inserted on the right side - default: false</li>
<li>breadcrumbs: path to current page from the root of our site - default: true</li>
</ul>
<p>Steps in tutorials are auto-generated: place <code class="language-plaintext highlighter-rouge"><div data-autosteps></div></code> inside of the page, and it will generate steps from h2 headings on that page.</p>
<h2 id="docs-as-code">Docs as code</h2>
<p>We work with the <a href="https://www.writethedocs.org/guide/docs-as-code/">docs as code</a> approach, which means that we treat our documentation content the same way as we treat our code. Documentation content goes through the same workflow stages and review process in the same tool, which is GitHub in our case.</p>
<p>We extended this approach to all aspects of our documentation site, and now we handle the whole editorial workflow and project management in the same tool. We keep track of content needs and content production on the Issues interface and kanban board of our documentation repository on GitHub. All of it is public, so you can watch issues and contribute to them, too.</p>
<h2 id="contribution">Contribution</h2>
<p>Contributors can contribute in different ways:</p>
<ul>
<li>Contribute to an issue, add questions, suggestions, or other comments </li>
<li>Open an issue</li>
<li>Edit content or code and send a pull request </li>
</ul>
<p>Users can contribute immediately from the page where they discover a problem or miss something by clicking on the feedback card. They can choose from two ways: 1. adding feedback or 2. contributing via GitHub. Clicking the “Contribute to this page” link opens the topic in the GitHub editor. </p>
<p><img src="/images/platformos/platformos_part4/feedback_block.png" alt="" /></p>
<h2 id="auto-generated-api-reference">Auto-generated API reference</h2>
<p>The information architecture of our <a href="https://documentation.platformos.com/api-reference/rest-api/customizations">API reference</a> was based on an API documentation template we built using the results of our discovery phase, API documentation best practices, existing templates (that we also contributed back to) and feedback from our community.</p>
<p>Our REST API documentation is auto-generated, always up-to-date, and remote. We download the JSON file, parse it, and render and cache the view on the server. JavaScript is only used to highlight code snippets (asynchronously) and generate the table of contents.</p>
<h3 id="implementation">Implementation</h3>
<h4 id="table-of-contents">Table of Contents</h4>
<p>We build the ToC on our API reference using a script that looks for headings in the content, and generates a list linking to them, to make it easier and quicker to jump to the content you’re interested in. This only happens when an author of a page sets toc: true in the page metadata. This way we can control which pages will get this helper and which don’t - some pages are just too short to benefit from it.</p>
<p><img src="/images/platformos/platformos_part4/toc.png" alt="" /></p>
<h4 id="deep-links">Deep links</h4>
<p>It is very convenient to link to specific sections of the page when you want to share a piece of information from a documentation page. Making links by hand and updating their anchors when text changes is very cumbersome, so we opted to automate that as well.</p>
<p>The link icon is added automatically to h2 and h3 headers, and the icons shows up when a user hovers over the heading.</p>
<p><img src="/images/platformos/platformos_part4/deep_links.png" alt="" /></p>
<h2 id="automated-tests">Automated tests</h2>
<p>As part of continuous integration and continuous deployment, we automatically run tests on our documentation site on each push to master. These are the steps of our deployment process including testing:</p>
<ol>
<li>Build</li>
<li>Deploy to staging</li>
<li>Run tests on staging</li>
<li>If tests passed: deploy to production</li>
<li>If tests failed: notify Slack, do not deploy</li>
</ol>
<p><img src="/images/platformos/platformos_part4/deployment_process.png" alt="" /></p>
<p>We use the <a href="https://devexpress.github.io/testcafe">TestCafe</a> framework for testing, because</p>
<ol>
<li>it’s fast, concurrency is supported</li>
<li>both tests and the framework are written in JavaScript</li>
<li>it comes with a Docker image so it’s easy to run on CI</li>
<li>it has good documentation</li>
<li>it is easy to extend with basic JavaScript knowledge</li>
<li>it supports remote browsers (ie. BrowserStack, SauceLabs)</li>
<li>it supports PageObject out of the box, which makes code organization easier</li>
<li>it produces artifacts from failed tests (screenshots/video) on CI</li>
<li>it has Roles which helps when there is a need to test two different users interacting</li>
<li>waiting for the network works well, which is rare.</li>
</ol>
<p>You can find <a href="https://documentation.platformos.com/best-practices/qa/installing-testcafe">extensive documentation on how to install and use TestCafe</a> on our documentation site, including topics on writing tests, using the Page Object model and testing performance.</p>
<p>When testing our documentation site, we check these elements:</p>
<ul>
<li>Menu</li>
<li>Lack of Liquid errors</li>
<li>Presence of contributors</li>
<li>Table of contents</li>
</ul>
<p>We also <strong>test the platformOS Liquid output</strong> by comparing the output of filters/tags with what we expect and catch regressions. Last line of defense after examples MP tests and integration tests in the platform.</p>
<p>We <strong>test broken links</strong> with a broken link checker that we run every 12 hours. The broken link checker reports the results to our dedicated Slack channel.</p>
<p>In the near future, we are planning to implement <strong>performance testing with real user metrics</strong>.</p>
<p>If you’d be interested in learning more about our process and tools, check out our article series on QA and testing:</p>
<ul>
<li><a href="https://www.platformos.com/blog/post/qa-and-testing-best-practices-part-1-our-qa-process">QA and Testing Best Practices — Part 1: Our QA Process</a></li>
<li><a href="https://www.platformos.com/blog/post/qa-and-testing-best-practices-part-2-tips-and-tricks">QA and Testing Best Practices — Part 2: Tips and Tricks</a></li>
<li><a href="https://www.platformos.com/blog/post/qa-and-testing-best-practices-part-3-speeding-up-development-and-troubleshooting">QA and Testing Best Practices — Part 3: Speeding Up Development and Troubleshooting</a></li>
<li><a href="https://www.platformos.com/blog/post/qa-and-testing-best-practices-part-4-performance-testing">QA and Testing Best Practices — Part 4: Performance Testing</a></li>
</ul>
<h2 id="performance">Performance</h2>
<p>If you read our article about <a href="https://www.platformos.com/blog/post/code-quality-and-performance-best-practices-for-your-platformos-site">Code Quality and Performance Best Practices for Your platformOS Site</a>, you know how good performance can help you keep visitors on your site, provide the best user experience, and rank high in search results. Our documentation is a high-performance site with a Google PageSpeed Insights score of 100 for both Mobile and Desktop, so we thought it could be helpful to dive a bit deeper into what tools we use and how we achieved this amazing performance.</p>
<h3 id="measure-early-measure-often">Measure early, measure often</h3>
<p>Before you start optimizing, you have an amazing opportunity to measure your current application performance using available tools. We recommend looking at them in this order:</p>
<ul>
<li><a href="https://web.dev/">https://web.dev/</a>: very easily digestible summary, uses <a href="https://developers.google.com/web/tools/lighthouse/">Lighthouse</a> underneath</li>
<li><a href="https://developers.google.com/speed/pagespeed/insights/">https://developers.google.com/speed/pagespeed/insights/</a>: more detailed report, with additional recommendations, uses Lighthouse underneath</li>
<li><a href="https://www.webpagetest.org/">https://www.webpagetest.org/</a>: you can choose client location, record video, force multiple views to test caching, network speed and others — highly recommended if you know what you are looking for</li>
<li><a href="https://github.com/GoogleChrome/lighthouse-ci">https://github.com/GoogleChrome/lighthouse-ci</a>: run Lighthouse on your CI to test performance continuously</li>
<li><a href="https://techglimpse.com/chrome-developer-tools-improve-site-speed/">Developer Tools</a>: all of the above, inside any Chromium based browser, uses Lighthouse underneath</li>
</ul>
<p>Export reports and repeat some of the measurements every month to see your progress. This can help correlate KPIs with web performance — but keep in mind that correlation does not equal causation.</p>
<h3 id="front-end-checklist--track-your-progress">Front-end checklist — track your progress</h3>
<p><a href="https://frontendchecklist.io/">Front-end checklist</a> is an excellent tool to track your front-end improvements progress. Checklists work well in teams if you can split work across multiple people. One person can handle SEO, while others can work on images and the performance sections of this checklist. All of them ultimately bring your application closer to being a successful project — making performance improvements a team effort makes the whole process even more satisfying.</p>
<p>Smashing Magazine recently published the <a href="https://www.smashingmagazine.com/2019/01/front-end-performance-checklist-2019-pdf-pages/">Front-End Performance Checklist 2019</a>. We highly recommend to read it from start to finish and come back to it often as a reference. It is available online and in various document formats. Most of the techniques used on our documentation page are described or at least mentioned in this article, so it should help you understand what we did.</p>
<p>There is also a community driven <a href="https://github.com/thedaviddias/Front-End-Performance-Checklist">Front-End Performance Checklist</a> that is basically a list of things to remember with links to resources that explain how to achieve the desired effects.</p>
<h3 id="the-most-important-performance-questions-when-developing">The most important performance questions when developing</h3>
<p>When you have control over both the server-side and the front-end, you have great power — which comes with great responsibility. Choose what you do on the backend wisely.</p>
<p>Doing more on the backend will slow down your <a href="https://varvy.com/pagespeed/ttfb.html">Time To First Byte</a>, but usually will mean less side effects and quicker <a href="https://calibreapp.com/blog/time-to-interactive/">Time To Interactive</a>. When you do more on the backend, after your feature is done, try caching the result if it can be done so easily and reliably. Sometimes caching is the only reason to move a feature from the backend to the frontend. For example, on our documentation page, we could not cache the main navigation because it had an active class on the current page menu, so we moved this part of the feature to JavaScript and saved around 50-100ms on rendering. 50ms doesn’t sound like much, but in this case it was an over 15% improvement.</p>
<p>If you decide to write some features in JavaScript, it will make your page bigger. Browsers will need to download, parse, execute and render that feature. This will usually mean quicker first meaningful paint, because you are basically lazy loading a feature from the server to asynchronous JavaScript. If you go this route, try not to block the main thread and use the <a href="https://philipwalton.com/articles/idle-until-urgent/">Idle until urgent</a> pattern by Philip Walton for minimized impact. Also see this <a href="https://www.youtube.com/watch?v=9vGr3JvbahY">video by Paul Lewis</a> for more visual explanation.</p>
<h3 id="what-to-avoid-how-to-fix-mistakes">What to avoid, how to fix mistakes</h3>
<p>The most common mistakes we see in the wild are around build processes and decisions on dependencies.</p>
<p>Looking at the list below will help you think about the balance between size, convenience, and maintainability:</p>
<p>Do you really need the whole Bootstrap? Or any CSS framework at all? Maybe purgeCSS can help get rid off unused code.</p>
<ul>
<li>Do you really need a JavaScript framework?</li>
<li>Can you format dates using modern APIs and provide conditional polyfill for legacy browsers?</li>
<li>What if you introduce a new developer to the project?</li>
<li>Is there any alternative that will not be dependency-heavy or will leverage native APIs?</li>
</ul>
<p>Using some development and asset building techniques allows you to mitigate the downsides of including some dependencies. We think these are the most impactful:</p>
<ul>
<li>Dynamic code splitting (with lazy loading chunks that are used on specific sites)</li>
<li>Tree shaking (smaller bundles)</li>
<li>Serving ES6 bundles to browsers that understand them, because it is smaller in size, and ES5 transpiled code to old browsers. Read more about this technique in <a href="https://medium.com/ghostcoder/using-es6-modules-in-the-browser-5dce9ca9e911">Using ES6 modules in the browser</a>.</li>
<li>Using modern features and Conditional polyfills (progressive enhancement) — verify browser support at <a href="https://caniuse.com/">caniuse.com</a></li>
</ul>
<p>Jump to the <a href="https://www.smashingmagazine.com/2019/01/front-end-performance-checklist-2019-pdf-pages/#quick-wins">Quick Wins</a> section from the Front-End Performance Checklist 2019 to read about the recommended 12 low-hanging fruits.</p>
<h3 id="what-we-did-to-achieve-100100">What we did to achieve 100/100</h3>
<p>Let’s explore the steps we took to ensure outstanding performance that made the perfect score possible for our documentation on Google Page Speed Insights:</p>
<ul>
<li>We replaced font icons with SVG icons. This improves rendering quality, it’s smaller and more flexible.</li>
<li>We self-hosted Google fonts. The fonts are also optimized to include only characters used on the website. This means instead of additional 2 HTTP requests and over 400KB to download, there is no HTTP request (apart from the font files themselves) and only 20KB to download.</li>
<li>We reduced third-party requests to an absolute minimum, even non-blocking ones. They can break performance of your website very quickly.</li>
<li>We use two external tools: The excellent <a href="https://polyfill.io">polyfill.io</a> service and sentry. We decided to self-host raven (sentry client) to save DNS lookups. One day we might decide to move to a self-hosted polyfill service as it is <a href="https://github.com/Financial-Times/polyfill-service">open source</a>.</li>
<li>We strip every package we use to the bare minimum using both manual and automatic methods, like <a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/src/css/vendor.scss">selective imports for bootstrap</a>.</li>
<li>We split code using <a href="https://webpack.js.org/guides/code-splitting/#dynamic-imports">webpack’s dynamic imports</a> to asynchronously load heavy dependencies on demand (<a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/src/js/syntaxHighlighting.js">prismjs</a>).</li>
<li>We <a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/marketplace_builder/views/partials/layouts/javascripts.liquid">preload resources</a> using the meta tag (JS, CSS, sometimes JSON with data).</li>
<li>We use <a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/marketplace_builder/views/partials/layouts/prefetch.liquid">DNS-prefetching</a> for domains that we will use (our CDN, polyfill service).</li>
<li>We sometimes use <a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/marketplace_builder/views/pages/home.liquid#L24">inline SVG</a> images to avoid http requests.</li>
<li>We <a href="https://github.com/mdyd-dev/nearme-documentation/blob/f4d78da3c108a119aa2c899a1526ff5394e9c9ee/marketplace_builder/views/partials/layouts/contributors.liquid">cache github contributors in the database</a> to move this feature to server side and remove missing contributors when a user enters the page.</li>
</ul>
<p>All of the above steps allowed us to get great results in both benchmarks and real user testing: </p>
<p><strong>Desktop results 100/100</strong></p>
<table>
<tbody>
<tr>
<td>First Meaningful Paint</td>
<td>300ms</td>
</tr>
<tr>
<td>Time To Interactive</td>
<td>600ms</td>
</tr>
</tbody>
</table>
<p><img src="/images/platformos/platformos_part4/page_speed_desktop.jpg" alt="" /></p>
<p><strong>Mobile results 100/100</strong></p>
<table>
<tbody>
<tr>
<td>First Meaningful Paint</td>
<td>1.6s</td>
</tr>
<tr>
<td>Time To Interactive</td>
<td>1.8s</td>
</tr>
</tbody>
</table>
<p><img src="/images/platformos/platformos_part4/page_speed_mobile.png" alt="" /></p>
<p>In the future, we are planning to use service workers to cache whatever can be cached for offline usage. We will also rewrite the frontend to TailwindCSS to get rid of Bootstrap.</p>
<h2 id="conclusion">Conclusion</h2>
<p>We hope you enjoyed our article series about how we built our documentation site on platformOS. We provided some insights into our processes and implementation, but we are continuously changing and improving all aspects of our documentation, so by the time you read these articles, some things might have changed.</p>
<p>We collect user feedback through Slack channels, the feedback block, user research and interviews to make sure our documentation fits our users’ needs. Some areas we would like to focus on in the next phase:</p>
<ul>
<li>Onboarding: We will do a full overhaul of our onboarding, and have three distinct user journeys for the three main segments of our target audience (non-technical, semi-technical, technical).</li>
<li>Design adjustments: We got a lot of valuable feedback on our design from both users and award juries, and we’re in the process of rolling out our branding to all of our sites, so we will do a design update on our documentation as well. </li>
<li>Examples: The more examples, the better. We are continuously working on adding more examples and considering to incorporate our example library into our documentation site.</li>
</ul>
<p>We’ve come a long way but there’s still a lot we can improve. Stay tuned, because we will write more articles to support you on your journey with platformOS.</p>
<p><em>This article was co-authored by Pawel Kowalski, Front-End Developer and Performance Advocate at platformOS, and was originally written for the <a href="https://www.platformos.com/blog/post/building-our-documentation-site-on-platformos-part-2-content-production-and-layouts">PlatformOS Blog</a>.</em></p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/platformos-4of4/">Building Our Documentation Site on platformOS — Part 4: Implementation</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on February 26, 2020.</p>
https://www.docslikecode.com/articles/github-pages-python-sphinx2019-04-20T00:00:00+00:002019-04-20T00:00:00+00:00https://www.docslikecode.com
<p>If you prefer to write in ReStructured Text instead of Markdown for your technical documentation, you’re in good company. There are quite a few benefits to using Sphinx, Python, RST, and Sphinx extensions because these tools are custom-built with developer documentation in mind.</p>
<p>Another great offering is GitHub Pages, with automatic publishing when a known branch, such as the <code class="language-plaintext highlighter-rouge">master</code> or <code class="language-plaintext highlighter-rouge">gh-pages</code> branch is updated.</p>
<p>So, how about the best of both? Let’s dive into the key configurations that enable you to publish Python Sphinx pages to GitHub Pages.</p>
<h2 id="naming-the-github-repository-can-affect-the-resulting-url">Naming the GitHub repository can affect the resulting URL</h2>
<p>If you want a URL like <code class="language-plaintext highlighter-rouge"><username>.github.io</code> or <code class="language-plaintext highlighter-rouge"><orgname>.github.io</code>, name the repo <code class="language-plaintext highlighter-rouge"><username>.github.io</code> or <code class="language-plaintext highlighter-rouge"><orgname>.github.io</code>. Then, by default, GitHub Pages publishes to the URL matching the repo name.</p>
<h2 id="enable-github-pages-for-the-github-repository">Enable GitHub Pages for the GitHub repository</h2>
<blockquote>
<p>Note: You must have admin privileges on the repository to see the <strong>Settings</strong> tab.</p>
</blockquote>
<ol>
<li>Go to the repository on the GitHub website and make sure you are logged in.</li>
<li>Add a <code class="language-plaintext highlighter-rouge">/docs</code> directory to the <code class="language-plaintext highlighter-rouge">master</code> branch. Otherwise you do not get the <strong>master branch /docs folder</strong> for the Source option in the drop-down list.</li>
<li>Click the <strong>Settings</strong> tab. You first go to the Options section.</li>
<li>Scroll down to the <strong>GitHub Pages</strong> section and choose the drop-down list under Source.
<blockquote>
<p>Note: Your choices will differ based on whether you’re in a User repo or an Org repo. <a href="https://help.github.com/en/articles/user-organization-and-project-pages">Read all about the differences in the GitHub docs</a>.</p>
</blockquote>
</li>
<li>To keep source and output HTML separate, choose <strong>master branch /docs folder</strong> for Source.</li>
</ol>
<p>Next, you set up the <code class="language-plaintext highlighter-rouge">.nojekyll</code> file to indicate you aren’t using Jekyll as your static site generator in this repository.</p>
<h2 id="add-a-nojekyll-file-in-the-docs-directory">Add a .nojekyll file in the /docs directory</h2>
<p>When GitHub sees a <code class="language-plaintext highlighter-rouge">.nojekyll</code> file, it serves the root <code class="language-plaintext highlighter-rouge">index.html</code> file. Read more in the <a href="https://github.blog/2009-12-29-bypassing-jekyll-on-github-pages/">original blog post about this feature</a>.</p>
<blockquote>
<p>Note: I’d recommend using the <code class="language-plaintext highlighter-rouge">/docs</code> directory on the <code class="language-plaintext highlighter-rouge">master</code> branch, so that you are sure to keep source and output HTML separate. You could also use a <code class="language-plaintext highlighter-rouge">_build</code> directory in the root of your repo as the served HTML.</p>
</blockquote>
<ol>
<li>Create a new branch locally, named <code class="language-plaintext highlighter-rouge">docs-config</code> in this example, based on <code class="language-plaintext highlighter-rouge">master</code>:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git checkout -b docs-config
</code></pre></div> </div>
</li>
<li>Create an empty dot file, named <code class="language-plaintext highlighter-rouge">.nojekyll</code> within the <code class="language-plaintext highlighter-rouge">/docs</code> folder of your repo. A dot file has a period prefix and may not be visible in all text editors or your Finder windows, so be aware and don’t panic if you can’t “see” it later.</li>
<li>Use the add command to make sure Git starts tracking the file:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git add docs/.nojekyll
</code></pre></div> </div>
</li>
<li>Commit the change with the <code class="language-plaintext highlighter-rouge">-a</code> option to add new files to the commit, and the <code class="language-plaintext highlighter-rouge">-m</code> option for a message:
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git commit -a -m "Adds a .nojekyll file for docs builds"
</code></pre></div> </div>
</li>
<li>Push the change to the remote, in this case named “origin”, so you can compare the change to <code class="language-plaintext highlighter-rouge">master</code>.
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>$ git push origin docs-config
</code></pre></div> </div>
</li>
<li>On the GitHub website, go to your repository and create a Pull Request.</li>
<li>Merge the Pull Request to add the <code class="language-plaintext highlighter-rouge">.nojekyll</code> file to the <code class="language-plaintext highlighter-rouge">master</code> branch.</li>
</ol>
<h2 id="create-a-docsource-or-docsrc-folder-for-the-source-files">Create a “docsource” or “docsrc” folder for the source files</h2>
<p>Now, in the root of your repository, you can create a source folder for your doc builds:</p>
<ul>
<li>If you’re working with code and docs in the same repo, you can name the folder <code class="language-plaintext highlighter-rouge">docsource</code> or <code class="language-plaintext highlighter-rouge">docsrc</code>.</li>
<li>If your repo is for only documentation, you can name the folder <code class="language-plaintext highlighter-rouge">source</code>.</li>
</ul>
<p>Next, make sure that your <code class="language-plaintext highlighter-rouge">conf.py</code> file has been set up with these source and destination directories. The Sphinx documentation has a good <a href="https://www.sphinx-doc.org/en/master/usage/configuration.html">Configuration section</a>.</p>
<h2 id="make-sure-you-can-still-build-sphinx-locally-for-reviews">Make sure you can still build Sphinx locally for reviews</h2>
<p>Here’s another pro tip I found while browsing <a href="https://github.com/sphinx-doc/sphinx/issues/3382#issuecomment-470772316">Issues in the Sphinx repository itself</a>. Since you want to keep the source and output separate, but still be able to both publish on GitHub Pages and preview builds locally, you can add an option to your <code class="language-plaintext highlighter-rouge">Makefile</code> to do both.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code> github:
@make html
@cp -a _build/html/. ../docs
</code></pre></div></div>
<p>Now you can run <code class="language-plaintext highlighter-rouge">make github</code> from the doc source directory to generate a local preview and move the docs where GitHub wants to serve them from.</p>
<blockquote>
<p>Note: Realize that there’s a <code class="language-plaintext highlighter-rouge">conf.py</code> setting for both where the <code class="language-plaintext highlighter-rouge">make</code> command is run and where files are built to. Read up in the <a href="https://www.sphinx-doc.org/en/master/usage/configuration.html">Configuration section</a> of the Sphinx docs for all the details.</p>
</blockquote>
<h2 id="pull-it-all-together">Pull it all together</h2>
<p>I’ve been working on a talk titled, “Make an Instant Web Site with Webhooks” for DevNet Create. In it, I show how to publish and host on GitHub Pages, which is built to use Jekyll by default, using Python Sphinx instead. I’ve got a GitHub repository set up at <a href="https://github.com/annegentle/create-demo">annegentle/create-demo</a> as a demonstration. I’ll post the slides when it’s done. In the meantime, we’d love to see you next week! Visit the <a href="https://developer.cisco.com/devnetcreate/2019">DevNet Create site</a> for more information.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/github-pages-python-sphinx/">Yes You Can Use GitHub Pages with Python Sphinx</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on April 20, 2019.</p>
https://www.docslikecode.com/articles/platformos-3of42018-11-25T00:00:00+00:002018-11-25T00:00:00+00:00Diána Lakatoshttps://www.docslikecode.com
<p>In this <a href="/articles/platformos-1of4">article series</a> we describe the process of building the <a href="https://documentation.platformos.com/">platformOS documentation site</a> from discovery to development, with in-depth insights into our approach, decisions, plans, and technical implementation. Welcome to part 3, where we explore how we collaborate with our community.</p>
<h1 id="community-driven-documentation">Community-driven documentation</h1>
<p>Knowing our target audience is key to great documentation, so being able to get to know our users and directly communicate with them is a huge advantage. As we have an amazing relationship with our community, we decided to involve them in all phases and aspects of our documentation process.</p>
<p>Engaging them early on in an agile and iterative process ensured that we can test and validate all of our assumptions, and quickly modify anything if needed. This is a time and cost-efficient approach: Although we edit and rewrite our content and change things on our documentation site all the time, we don’t run the risk of creating large chunks of work that have to be thrown away because they don’t correspond to the needs of our users.</p>
<p>Constant collaboration also builds trust: as our process is completely transparent, our community continuously sees what we’re working on and how our docs evolve, and community members can be sure that their opinions are heard and acted upon.</p>
<p>Involving the community from an early stage means that our users will see lots of stuff that’s partially done, missing, or will be totally rewritten. So, for all of this to work, our users have to be mature enough to give feedback on half-done content.</p>
<h2 id="contributor-experience">Contributor Experience</h2>
<p>We’d like to serve a diverse, highly motivated, active community, and provide everything they need to contribute to our documentation. To find the most fitting tools and workflow, we had to think about contributor experience (CX) first, and explore what makes a great CX when contributing to documentation. Here are the aspects we considered and how we addressed them:</p>
<ul>
<li><strong>Ease of getting on board</strong>: We describe ways for our community members to get involved in our contributor guide. We made the guide as short as possible (less than a page) with links to relevant content (e.g. style guide, templates).</li>
<li><strong>Entry points for different types of contributors</strong>: We wanted to make it very easy to get involved for all segments of our target audience, so we offer different ways to contribute both regarding the time contributors have to put in and the skill level they need.
<ul>
<li>For quick feedback, we added a feedback block at the bottom of each documentation page, where the minimum input is clicking on a smiley, but users can answer a question and share their suggestions, too.</li>
<li>For some quick editing, like fixing typos or adding links, contributors can edit the content easily on the GitHub UI.</li>
<li>For heavy editing, adding new content, or developers who prefer to use git, we provide a complete docs as code workflow.</li>
</ul>
</li>
<li><strong>Clear expectations</strong>: We know it’s easier to get started on editing or writing a topic with clear guidelines to follow. Our <a href="https://documentation.platformos.com/style-guide/documentation-style-guide">style guide</a> contains guidelines for writing technical content (e.g. language, tone, etc.) and each content type in our documentation (e.g. tutorials, concept topics, etc.).</li>
<li><strong>Ease of contribution</strong>: To make contribution easier and to keep content on our documentation site consistent, we created <a href="https://github.com/mdyd-dev/nearme-documentation/tree/master/marketplace_builder/views/pages/doc-templates">templates</a> for all content types. The templates provide an outline and instructions that contributors can follow.</li>
<li><strong>Clear workflow</strong>: We developed an editorial workflow that works for both internal and external contributors, and ensures that contributors get quick and precise feedback.</li>
<li><strong>Familiar tools</strong>: We chose a tool that most of our target audience is familiar with, GitHub. As our users usually already use git or some other version-control system, extending its use to external content contributors was a logical step.</li>
<li><strong>Appreciation</strong>: We thank all of our contributors, and display them on our GitHub repository’s README page, and on each topic on the documentation page.</li>
</ul>
<p><img src="/images/platformos/platformos_part3/contributors.png" alt="" /></p>
<p><em>Contributors displayed on a documentation topic</em></p>
<h1 id="communication">Communication</h1>
<p>In order to encourage collaboration and keep our community up-to-date with what we’re doing, we are consciously building and extending our channels of communication. We provide different types of communication channels (asynchronous, real-time, face-to-face, etc.) to accommodate community members with different schedules and communication styles.</p>
<h2 id="slack-channel">Slack channel</h2>
<p>Our main communication channel for now is a dedicated Slack channel, where community members <strong>ask questions, share ideas, and get to know our team members and each other</strong>.</p>
<p>Here, they can ask questions about anything related to platformOS, and someone from our team, or another community member who has the answer will jump in to reply. We get a wide variety of questions from business related enquiries like pricing to specific questions about development.</p>
<p>This is also the place where both we and our community members <strong>share news</strong>. We let them know of new <strong>features planned, bugs fixed, articles posted, and new docs added, and they show what they’re building on platformOS</strong>. This constant exchange of information is extremely valuable for all involved: community members can share what they’ve learned, plan their module development in sync with our roadmap and each other’s projects, and allocate their resources according to what’s going on in the business and the wider community.</p>
<p>The Slack channel also provides a great opportunity for community members to start conversations, share relevant news and articles, and engage with like-minded professionals.</p>
<p><img src="/images/platformos/platformos_part3/slack.png" alt="" /></p>
<p><em>A conversation in our Slack channel</em></p>
<p>Being actively involved with the community through the Slack channel helps us see how to shape our documentation. Questions are good indicators of what needs to be documented, and when we share news of new topics added to our docs or our plans for future changes, we can get immediate feedback.</p>
<h2 id="documentation-status-reports">Documentation Status Reports</h2>
<p>To keep our community up-to-date with the work on our documentation, we share weekly status reports each Monday. The status reports include what we’ve been working on the previous week, what topics we added, what we are planning and any other news regarding our documentation.</p>
<p>The status reports were a request from the community to have a regular digest of what’s going on. Based on further requests, we now also send the reports to subscribers as a newsletter (through our SendGrid integration), so that they can easily access them in their mailboxes and share them with their developer teams.</p>
<p><img src="/images/platformos/platformos_part3/status_report.png" alt="" /></p>
<p><em>A documentation status report in our Slack channel</em></p>
<h2 id="weekly-video-conferencing">Weekly video conferencing</h2>
<p>Initiated by our community, Town Hall is a weekly video conference over <a href="https://zoom.us/">Zoom</a>, where community members and the platformOS team share news, demo features and modules, and have the opportunity to engage in real-time, face-to-face conversation.</p>
<p>Our team and community members are distributed over different continents, so we try to accommodate participants in different time zones by rotating the time of this event so that everyone has the chance to participate. We also share the recording of each meeting.</p>
<p><img src="/images/platformos/platformos_part3/town_hall.jpg" alt="" /></p>
<p><em>Town Hall meeting: A community member demoing an application he developed on platformOS</em></p>
<h2 id="surveys">Surveys</h2>
<p>Besides getting constant feedback from the community through the channels described above, we plan regular checkpoints in our process to facilitate testing and course-correction. During development, we tie these checkpoints to development phases. At the end of each larger release, we compile and share a short survey for community members to fill out.</p>
<p>Our documentation site is in alpha now, so we’ve had our first survey round a couple of weeks ago. We put together a short 10 item questionnaire collecting both quantitative and qualitative data.</p>
<ul>
<li>The 5 quantitative questions showed an average value to help us identify how much users like the whole site, the information structure, and the performance, and how they would rate understandability and trustworthiness. We are planning to reuse these questions in later questionnaires to compare the results and validate how our changes affected user satisfaction. These questions are also benchmarked by SurveyMonkey, which allows us to compare our results to others who used the same website feedback questions.</li>
<li>We also included 5 qualitative questions to explore the reasons behind the scores of the quantitative ones. Our main goal was to have a general idea of how users think about the site. The results helped us identify what they’d like to keep, what we should change, and highlighted areas to focus on.</li>
</ul>
<p>Based on our community members’ feedback and the results of our first questionnaire, we compiled a list of tasks and a roadmap for the beta phase, that includes a reorganization of main sections, subsections and topics, rewriting and editing topics, content production with a well-defined focus, and a couple of new features for the documentation site.</p>
<p>We are dedicated to engaging community members further as we are working on these next steps. For example, we started the reorganization with compiling a plan for the new content structure based on the feedback we received, but also asked if any community members would be interested in providing their ideas and reviewing ours. Two members got actively involved, and shared their opinions on our plan. We fine-tuned the plan in a call with them, making significant changes based on their valuable insights. Having the opportunity to directly collaborate with members of our target audience gave us a chance to quickly and easily verify our ideas, and work out an approach that would best suit our users’ needs. Once done, we shared the plan with our community to see what they think about it. Reorganization started based on this plan that many contributed to and everyone agreed on.</p>
<h1 id="future-plans">Future plans</h1>
<p>As our community grows, we are preparing to scale with it. Here are some of our plans for next year:</p>
<ul>
<li><strong>Topic wish list</strong>: A feature that allows community members to add topics they’d like to see documented.</li>
<li><strong>Voting on topics</strong>: Vote on topics, and we will start working on the topics with the most votes.</li>
<li><strong>Community site</strong>: Our community members are active on many channels now, including on some of their own initiatives, like an Airtable for keeping track of community members, questions and answers, and community activities. Although it works for now, we are planning to give the platformOS community a home — a site similar to Intel Devmesh, a developer community site we built for Intel on platformOS.</li>
<li><strong>Community Manager</strong>: In the near future, we are hiring a Community Manager to give the platformOS community dedicated attention from an experienced professional.</li>
<li><strong>Gamification</strong>: After building a solid user flow, we are planning to strengthen it with gamification elements to help and reward the user’s journey from onboarding to mastering the site.</li>
<li><strong>Devcon</strong>: We are planning a platformOS Devcon for 2019, a proper get-together for our community members with workshops and presentations by our team members and experienced members of our community.</li>
</ul>
<p>Now that you’ve seen how we discovered the needs of our target audience, planned content and layout for our documentation site, and connected with our community, all that’s left from our series is to show you how we implemented our documentation site on platformOS. See you again in part 4!</p>
<p><em>We involved <a href="https://www.linkedin.com/in/nagygyorgykatalin/">UX Strategist Katalin Nagygyörgy</a> in our process from the start. Through our collaboration, we could extract and collect all the necessary information using tried and true research methodologies and UX best practices.</em></p>
<p><em>This article was originally written for the <a href="https://www.platformos.com/blog/post/building-our-documentation-site-on-platformos-part-3-community">platformOS Blog</a>.</em></p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/platformos-3of4/">Building Our Documentation Site on platformOS — Part 3: Community</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on November 25, 2018.</p>
https://www.docslikecode.com/articles/moving-agile-open-source-docs2018-11-15T00:00:00+00:002018-11-15T00:00:00+00:00Ben Mansheimhttps://www.docslikecode.com
<p>“Open source” carries a lot of meaning in the world of technology these days. Twenty years after the term was coined, open source projects harness the power of voluntary contributors to produce and support software that is quickly growing in its impact on every industry, in every location.</p>
<p>At its core, open source merely means that a product ships with the code that was written to produce it. The ability to access this source code creates the potential for modification and repackaging that is governed by a variety of open source licenses. It also can allow people to contribute modifications back into the core project, so that everyone benefits from those modifications.</p>
<p>As a software company built on the principles of providing superior service while also promoting the common good, we at <a href="https://www.redis.com">Redis</a> decided to bring this open source agility to a less known, but highly impactful, area – Product Documentation.</p>
<p>We feel that joining open source with documentation is a great combination to provide our community with:</p>
<ul>
<li>Information that is always current</li>
<li>A platform for collaborative contributions from others</li>
<li>Highly accurate details from a dedicated community</li>
</ul>
<p>To find out how you can contribute, check out our <a href="https://docs.redis.com/latest/contribution-guide/">contribution guide</a>.</p>
<p>So why did we decide to take the open source route for documentation? To understand, let’s look at the evolution of technical documentation over the last few years.</p>
<h2 id="the-last-revolution---closing-the-delivery-gap">The Last Revolution - Closing the delivery gap</h2>
<p>It used to be that documentation was a stumbling block in software development deadlines because all supported explanations surrounding the use of the software had to be delivered at the same time as the software itself. Worse, it started off as printed material (think user guides!) that were not only slow to create but even harder to update.</p>
<p>Fortunately, as technology progressed, we were able to update user documentation in digital formats, saving on the “heavy” costs of printing and shipping. Writers could provide corrections, rewrites and updates to customers just as easily as engineers could provide patches to software.</p>
<p>This revolution closed the delivery gap to enable companies to improve documentation during the lifetime of the product. However, there were still significant bottlenecks preventing customers from getting the best information possible.</p>
<h2 id="another-pain-point---i-am-a-bottleneck">Another Pain Point - I am a bottleneck</h2>
<p>So, what traditionally stood in the way of getting the most accurate product information out there? The WRITER!</p>
<p>The technical writer is the sole content contributor who stands between technical experts and customers to provide technical information that customers can use reliably and efficiently. Granted, a product without technical writers may be difficult to use, but the time and effort that it takes for a writer to understand the information well enough to write is another bottleneck.</p>
<p>Since technical writers are frequently the only ones with access to the source files for published documentation, any correction, rewrite or update contribution has to be entered and produced into its final format by them.</p>
<h2 id="the-next-revolution---open-source-docs">The Next Revolution - Open source docs</h2>
<p>Open source gives everyone some level of access to the source files of the product. In the case of Redis docs, that means putting the source files of our documentation in a publicly accessible repository. Anyone can view those source files and edit a copy of the files to suggest contributions, changing the writer from the content owner to the content editor and curator. You can even get there straight from the “Edit on GitHub” link on each page in our docs.</p>
<p>This simple change in methodology opens ownership of the documentation’s accuracy to the technical experts within Redis, as well as our customers and partners who are experiencing the product’s behavior every single day. Add that to the immediate delivery of approved contributions at <a href="https://docs.redis.com">docs.redis.com</a>, and we have dramatically improved our ability to provide up-to-the-moment and accurate documentation for our customers.</p>
<h2 id="were-not-stopping-now">We’re Not Stopping Now</h2>
<p>Of course, this is only the beginning of the improvements we are bringing to our product documentation, but we feel that this move will be the basis for a lot of good stuff to come.</p>
<p>So if you want to be a part of helping everyone get the most out of the fastest database in the world, don’t hesitate – Contribute!</p>
<p><a href="https://www.docslikecode.com/articles/moving-agile-open-source-docs/">Redis - Moving to Agile, Open Source Docs</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on November 15, 2018.</p>
https://www.docslikecode.com/articles/platformos-2of42018-11-01T00:00:00+00:002018-11-01T00:00:00+00:00Diána Lakatoshttps://www.docslikecode.com
<p>Welcome to part 2 of our article series where we describe the process of building the <a href="https://documentation.platformos.com/">platformOS documentation site</a> from discovery to development, with in-depth insights into our approach, decisions, plans, and technical implementation.</p>
<p>Now that you’ve seen how we explored the needs of our audience, outlined the types of content we’d work on, and created a sitemap in part 1, let’s move on to discuss how content production started, and how we created the layouts and navigation for the site.</p>
<h1 id="content-first-design">Content-first design</h1>
<p>The goal of a documentation site or developer portal is to provide easily accessible, well-structured information for self-support and learning. As opposed to a sales landing page or a webshop, the aim of a documentation site is not to persuade or allow the visitor to complete tasks (e.g. buy something), but to provide information that is written, edited, and structured in a way that best fits the user’s needs.</p>
<p>Because technical writing (and all writing with the purpose to eventually be read) should start with knowing who you write for, we started with an in-depth exploration of our audience. Right during the discovery phase, we made all our decisions based on our personas and what we’ve learned about them. Now, that we had an idea of what they needed, we wanted to explore what types of content we’ll create for them, and think about the display of the content only after that. This is what content-driven design means: we make sure that content is our top priority, and we start designing with existing content (or templates) instead of dummy text to be able to see what design would fit best around it — and not the other way around where you have designs signed off before you start to produce any content, and then desperately try to come up with copy that you could pour into the design.</p>
<h2 id="community-contributions">Community contributions</h2>
<p>Right from the start, we knew that we wanted to build a community-driven documentation site, meaning we wanted to provide all the tools and encouragement for our users to contribute to our docs.</p>
<p>As we planned to go back and re-evaluate all of our initial assumptions, we welcomed feedback through many different channels, like the built-in feedback block on each page, Slack channels dedicated to our early adopters, surveys at the end of each development phase, email, weekly community meetings, etc.</p>
<p><img src="/images/platformos/platformos_part2/feedback_block.png" alt="" /></p>
<p><em>Feedback block at the bottom of each page</em></p>
<p>We also wanted to provide tools to make it easy for our users to contribute documentation topics or edit existing pages. We follow a docs like code approach: you can contribute to our docs through GitHub. To preserve consistency and help our contributors get started, we created a content framework and editorial workflow that user contributions can be an integral part of.</p>
<h1 id="style-guide">Style Guide</h1>
<p>To ensure a consistent communication style throughout our documentation, we started with defining our standards for grammar, syntax, and the different types of technical content we have, in our <a href="https://documentation.platformos.com/style-guide/documentation-style-guide">style guide</a>.</p>
<p>Our style guide is just as much a work in progress as our documentation, but we’ve defined the basics that internal or external contributors need:</p>
<ul>
<li><strong>Grammar and syntax</strong> correspond to the <a href="https://www.chicagomanualofstyle.org/home.html">Chicago Manual of Style</a>. We didn’t try to reinvent the wheel here, we chose a well-known style guide that works for us.</li>
<li>Our documentation consists of different types of topics, like tutorials, concepts, references (e.g. API documentation). To help contribution both for writers and editors, we specified the structure of each content type in <strong>ready-to-use templates</strong>.</li>
<li>Contributors are welcome to edit our style guide just like they are welcome to edit any documentation topic.</li>
</ul>
<h1 id="templates">Templates</h1>
<p>Our site uses Liquid pages, but to make editing easier for contributors, we write documentation content in GitHub Flavored Markdown and use a Markdown converter to turn it into Liquid. Our <a href="https://github.com/mdyd-dev/nearme-documentation/tree/master/marketplace_builder/views/pages/doc-templates">templates</a> include all non-changeable content, and placeholders with explanations for the parts to add. Placeholders provide information on the recommended format (e.g. title), and any requirements or limitations (e.g. maximum number of characters). Recurring sections, like the question block at the bottom of each page, are added using a partial.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>---
converter: markdown
metadata:
title: [TITLE, format: VERBing a(n)/the NOUN(s)]
description: [short description of the topic, can reuse first sentence, max 300 characters]
slug: get-started/install-docker-example
searchable: true
---
This guide will help you [describe what the user will achieve by the end of the guide]. [Explain goal, domain-related background information, any information that helps understand the purpose or terminology of the tutorial.]
## Requirements
[List of requirements with links (internal or external) and explanations where needed. ]
- [Requirement 1: explanation if applicable]
- [Requirement 2: explanation if applicable]
- [Requirement 3: explanation if applicable]
## Steps
[Purpose of the tutorial/title] is a [number of large steps, e.g. two]-step process:
1. [step 1 short description, format VERB the/a(n)/your NOUN]
2. [step 2 short description, format VERB the/a(n)/your NOUN]
### Step 1: [VERB the/a(n)/your NOUN]
[Full description of step with additional content, like code snippet, screenshot, etc.]
### Step 2: [VERB the/a(n)/your NOUN]
### Step 3: [VERB the/a(n)/your NOUN]
## Live example and source code
[optional: link to live site or source code on GitHub]
## Additional resources
[optional: bulleted list to additional external resources]
## Next steps
Congratulations! You have [what the user has achieved].
[Describe what the user can/has to do next.]
- [Link to next tutorial]()
- [Other link to next tutorial - if applicable]()
{% include 'shared/questions_section' %}
</code></pre></div></div>
<p><em>Tutorial template</em></p>
<h1 id="editorial-workflow">Editorial workflow</h1>
<p>We built an editorial workflow that works for all participants (writer, developer, contributor, etc.) and all stages of the process (writing, reviewing, editing). As mentioned before, we treat our docs like code, each stage of our workflow is in git:</p>
<ol>
<li>Write new content in Markdown using the templates. You can use any editor that can produce Github Flavored Markdown.</li>
<li>Submit the new topic as a pull request on Github.</li>
<li>Review. We have a peer-review system in place for code and docs alike. Topics are reviewed by both technical reviewers (developers) and writers.</li>
<li>Edit as needed. Repeat step 3-4 until approved.</li>
<li>Merge approved pull request.</li>
<li>Deploy to staging, then production.</li>
</ol>
<p><img src="/images/platformos/platformos_part2/editorial_workflow.png" alt="" /> </p>
<p><em>A documentation topic going through the editorial workflow on Github.</em></p>
<p>For changes, we follow a similar process. We open a pull request with our edits to a topic, and then the changes go through the same review steps.</p>
<h1 id="wireframes">Wireframes</h1>
<p>Once we finalized the templates (remember, finalizing means “final for now, but can be tweaked later”), and produced some initial content, we had everything we needed to start thinking about the layouts of different pages. We used what we’ve learned about our personas from the first phase, and collected patterns to identify how to best serve our audience. That helped us create the first wireframes, sketches of our user interfaces without any branding or design, that we iterated based on team feedback. We created wireframes for each layout in <a href="https://balsamiq.com/">Balsamiq</a>, and collaborated on them in <a href="https://marvelapp.com/">Marvelapp</a>. </p>
<p>We also thought about how we can evolve these pages in the future, and created separate wireframes or concepts for later development phases. This helps us plan our site development process. As we deeply rely on user feedback, we are prepared to iteratively adjust our layouts.</p>
<p><em><img src="/images/platformos/platformos_part2/wireframe_tutorial.png" alt="" /></em></p>
<p><em>Wireframe for the tutorial topic type</em></p>
<h1 id="design">Design</h1>
<p>As you can see from the process so far, we put our focus on audience, content, and UX — leaving visual design for later.</p>
<p>Both the Design Thinking approach, and the Content-First approach we described in this article push visual design to a later stage. At the same time, the branding of platformOS is still in the making — with the help of the wonderful <a href="https://www.linkedin.com/in/yiyinglu/">Yiying Lu</a>. This means, that by the time our branding is done, we will have a working documentation site tested with real users, continuously improved based on relevant feedback. We believe that this way we could focus on the most important aspects for each phase, and our documentation site will have a solid foundation that the design can enhance. This is why, for now, we went with a very simple, clean design.</p>
<p>We hope you enjoyed learning about how we started content production, how we built our editorial workflow, and how we created wireframes for our documentation site. <strong>Stay tuned to learn more about the community aspects of our docs in part 3 of our series!</strong></p>
<p><em>We involved <a href="https://www.linkedin.com/in/nagygyorgykatalin/">UX Strategist Katalin Nagygyörgy</a> in our process from the start. Through our collaboration, we could extract and collect all the necessary information using tried and true research methodologies and UX best practices.</em></p>
<p><em>This article was originally written for the <a href="https://www.platformos.com/blog/post/building-our-documentation-site-on-platformos-part-2-content-production-and-layouts">platformOS Blog</a>.</em></p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/platformos-2of4/">Building Our Documentation Site on platformOS — Part 2: Content Production and Layouts</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on November 01, 2018.</p>
https://www.docslikecode.com/articles/platformos-1of42018-10-12T00:00:00+00:002018-10-12T00:00:00+00:00Diána Lakatoshttps://www.docslikecode.com
<p>This article series describes our process of building our <a href="https://documentation.platformos.com/">documentation site</a> for <a href="https://www.platformos.com/">platformOS</a>, with in-depth insights into our approach, decisions, and plans. We have planned four parts for this series, each describing a unique aspect of our journey:</p>
<ul>
<li>Part 1: <strong>Information Architecture</strong><br />
In this part, we share how we started, how we got to know our audience, how we figured out what content we need, and how we outlined a sitemap for our documentation site.</li>
<li>Part 2: <strong>Layouts and Content Production</strong><br />
In this part, we discuss how we started building templates and wireframes, how we approached the design, and how we started producing content.</li>
<li>Part 3: <strong>Community</strong><br />
We build our site for our community. Learn more about community-driven documentation, and the mechanisms we built in to support our users and continuously improve our docs, like feedback options, contribution through GitHub, pre-made templates for each content type, and a style guide to make it easier to keep everything consistent.</li>
<li>Part 4: <strong>Implementation</strong><br />
In this part, we take a look under the hood, and discuss the technologies we used, how we built our auto-generated API Reference, and how we pull content and related information from Github. We also share our future plans with you.</li>
</ul>
<p>All these articles together will show you a complete framework for building a documentation site on platformOS.</p>
<p>We are continuously working on our documentation, but decided to make it public early on to get valuable feedback and show you the whole process, so please expect the documentation site to change and evolve while you learn more about it through these articles. At the time of the publication of this article, our documentation site is in alpha.</p>
<h1 id="building-information-architecture-through-design-thinking">Building Information Architecture through Design Thinking</h1>
<p>Because of the strategic role our documentation plays in the adoption and use of our product, we approached the development of our docs with a mindset that ensures that:</p>
<ul>
<li>Our community gets the most out of our documentation as early on as possible.</li>
<li>We receive feedback as soon as possible.</li>
<li>We never lose sight of our long-term goals.</li>
</ul>
<p>All throughout the process, we used the user-centered, solution-based <a href="https://en.wikipedia.org/wiki/Design_thinking">Design Thinking</a> method.</p>
<p><img src="/images/platformos/platformos_part1/design_thinking.png" alt="" /></p>
<p>At the start, we explored our audience, our documentation needs, existing and missing content through in-depth interviews and workshops. In Design Thinking terms, this was the <strong>Empathize</strong> phase. Then, we defined personas and our Content Inventory (<strong>Define</strong>), and shared our ideas for content and features through a Card Sorting exercise (<strong>Ideate</strong>). Based on our findings, we created a sitemap and prioritized content needs. Layouts, wireframes, and content production (<strong>Prototype</strong>) started based on the results of our discovery phase.</p>
<p>We decided to follow an iterative, docs like code approach: at each stage, we work with quick feedback rounds, deploy often (multiple times a week), and improve features and content based on feedback from real users (<strong>Test</strong>). We have an overarching plan outlined for our documentation that we keep in mind, but we always focus on the next couple of action steps we’d like to take.</p>
<h2 id="discovery">Discovery </h2>
<p>We knew that knowing our audience is the key to writing documentation that best supports their needs. For efficiency, we also needed to know what we already have, and how existing content could be reused. This is why we started our journey with a discovery phase. By asking the right questions, we got the answers we could build on, and outlined the Information Architecture and content needs of our documentation site.</p>
<h3 id="proto-personas">Proto-personas</h3>
<p>The first output from our workshops was a detailed description of each persona — the types of users that will be interacting with our documentation site. The user personas help team members share a specific, consistent understanding of various audience groups. We use these personas to see how well proposed solutions meet their needs, and to prioritize features based on how well they address the needs of one or more personas. We plan to revisit and revalidate these personas in later phases of the project as the product is evolving.</p>
<p>We found out that we have the following four main personas:</p>
<ul>
<li>Experienced Developers</li>
<li>Junior Developers</li>
<li>Site Builders</li>
<li>Marketplace Owners</li>
</ul>
<p><img src="/images/platformos/platformos_part1/protopersonas.jpg" alt="" /></p>
<p><em>Descriptions of our proto-personas with sample photos and names to make them easier to relate and refer to</em></p>
<h3 id="content-inventory">Content Inventory</h3>
<p>Taking into account our proto-personas’ needs and sites we considered our inspiration, we created a detailed list of content from our previous documentation site, and identified missing, reusable, and non-reusable content for our future site. </p>
<p><img src="/images/platformos/platformos_part1/content_inventory.png" alt="" /></p>
<p><em>Content Inventory ready for the Card Sorting Session</em></p>
<h3 id="card-sorting-sessions">Card Sorting Sessions</h3>
<p>Through a <a href="https://www.usability.gov/how-to-and-tools/methods/card-sorting.html">Card Sorting</a> exercise, we defined connected elements, and mapped out the best site structure for our goals and proto-personas.</p>
<p><img src="/images/platformos/platformos_part1/cardsorting.png" alt="" /></p>
<p><img src="/images/platformos/platformos_part1/cardsorting2.png" alt="" /></p>
<p><em>Screens from <a href="https://mural.co/">Mural</a> during our Card Sorting sessions</em></p>
<h3 id="sitemap">Sitemap</h3>
<p>Based on the Content Inventory and the results of the Card Sorting sessions, we outlined a sitemap for our future site. Our sitemap shows the structure of the site. We can also use it as a roadmap to keep track of site improvements, content needs, and project phases, because following our iterative approach, we created several sitemaps — one for each phase of the process (e.g. alpha, beta, etc.).</p>
<p><img src="/images/platformos/platformos_part1/sitemap.png" alt="" /></p>
<p><em>Sample page from our sitemap</em></p>
<p>We have already changed some parts of our sitemap based on new information we gathered and business decisions we made. For example, we are now planning to build a separate community site, instead of having a community section on our documentation site. We decided to link to content on <a href="https://www.platformos.com/blog/post/platform-os-blog-module">platformos.com</a> (like the blog, terms & conditions, etc.) in the beginning to focus on other parts of the site, and reevaluate these sections later. We believe that both product and content development can benefit from a process that allows for such flexibility.</p>
<h3 id="persona-based-content-prioritization">Persona-based content prioritization</h3>
<p>Now that we had data about the personas and our sitemap, we put the data into the proper context and outlined coherent stories. These stories, similar to user journeys, show the order of actions taken by the user personas during their interaction with the site. During the Card Sorting sessions, we explored areas of interest for each user persona. This helped us see where to focus first to help them from the beginning. We also validated the importance of these areas to assign higher priorities to the ones that need more attention. We then displayed their interaction with the site on the sitemap.</p>
<p><img src="/images/platformos/platformos_part1/userjourneys1.png" alt="" /></p>
<p><em>Exploring areas of interest based on the persona’s actions taken on the site</em></p>
<p><img src="/images/platformos/platformos_part1/sitemap_userjourneys.png" alt="" /></p>
<p><em>Persona interactions with the site displayed on the sitemap</em></p>
<p>This concluded our Information Architecture phase. We have discovered and organized all the information we needed to continue on to the next phase, where we started creating templates for content types, building the wireframes for each page, producing content, and making decisions about design.</p>
<p><strong>We will discuss these aspects in part 2 of our series. Stay tuned!</strong></p>
<p><em>We involved <a href="https://www.linkedin.com/in/nagygyorgykatalin/">UX Strategist Katalin Nagygyörgy</a> in our process from the start. Through our collaboration, we could extract and collect all the necessary information using tried and true research methodologies and UX best practices.</em></p>
<p><em>This article was originally written for the <a href="https://www.platformos.com/blog/post/building-our-documentation-site-on-platformos-part-1-information-architecture">platformOS Blog</a>.</em></p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/platformos-1of4/">Building Our Documentation Site on platformOS — Part 1: Information Architecture</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on October 12, 2018.</p>
https://www.docslikecode.com/articles/cloudify-dont-stop-dreaming2018-06-05T00:00:00+00:002018-06-05T00:00:00+00:00Ben Mansheimhttps://www.docslikecode.com
<p>When I signed on as the technical writer at <a href="https://cloudify.co/">Cloudify</a>, I was greeted by the VP of Marketing with, “we need you to join the discussions about the new docs platform.” I was happy that there was a process already started — and especially happy that they didn’t make the decision before I joined.</p>
<p>The existing documentation platform relied on markdown files edited in GitHub and built with a home-glued publishing platform based on the open source, static site generator named Hugo that everyone felt could fall apart any day.</p>
<p>In my 10 years in documentation I had never used or even heard of such a workflow. Usually writers write in authoring applications that produce the final product. I thought I would do a quick review of the requirements and solutions, and recommend one of the standard documentation tools I was used to. I was the expert, right? I certainly did not expect the discussions to result in an upgrade of the same Hugo platform that also required learning Git, Hugo, CircleCI, CSS, Docker, Bash — and many hours of learning how to put it all together to make <em>Docs as Code</em>. But that is exactly what I chose.</p>
<p>So this is the story…</p>
<h2 id="the-challenge">The Challenge</h2>
<p>The first task I received when I arrived at the company seemed simple. “Our sidebar table of contents (TOC) has a long list of top-level categories that are not well organized and confusing to our customers.” Well, sounds easy enough. To get started, we’ll make a hierarchy that simplifies those categories into 5 groups that basically match 5 types of users. Once we get that quick win we can then look at the content in the categories and combine information in the different topics to condense the content into fewer topics. I figured I could have that done in a week with a lot of buffer. My boss said, “Great!”</p>
<p><img src="../../images/cloudify/old-cloudify-docs.png" alt="Old Cloudify docs" /></p>
<p>(<a href="https://docs.cloudify.co/4.2.0">Old Cloudify Docs Site</a>)</p>
<p>Now, here are the pitfalls that I met along the way:</p>
<ul>
<li>The content is in one repo and the site configuration, including the TOC definition, is in another.</li>
<li>The top-level of the TOC is hard-coded instead of being based on directory structure.</li>
<li>All of the versions use the same TOC, so I can’t create a structure that includes newer content.</li>
<li>Each commit to git triggers a TravisCI build process that takes up to 5 minutes.</li>
<li>There were no internal resources to help me rework the TravisCI configuration because our company mainly worked with CircleCI.</li>
<li>With all of the required components, I couldn’t get a local build to work — on Windows, CentOS, or Ubuntu.</li>
<li>We were building with Hugo 0.16, but Hugo was now up to 0.36 with many added features and bug fixes.</li>
</ul>
<p>At the time, the discussions about the new docs platform focused on moving to some of the online services that pull your markdown from GitHub and produce a site from it. One after another I got stuck trying to get them to work with only small hints of success. My mentions of standard tools were met with, “Being an open-source company we should use open-source products. Besides, how would the developers contribute if it’s not in GitHub?” Good points, but I wasn’t finding a way to make it work.</p>
<h2 id="a-spark-of-light">A Spark of Light</h2>
<p>After a few weeks of struggling to learn where everything was and getting nowhere with alternative solutions, it occurred to me that, because the content was in markdown, maybe I could just upgrade to the latest version of Hugo without the added components and build locally? It took a lot of debugging of error messages but I finally got that to work!</p>
<p>Then I looked for a Hugo theme that looked good for documentation and found DocDock. It had a lot of the things that I wanted, including TOC based on directory structure , a main landing page, expanding blocks, single-sourced excerpts, and greatly improved search functionality. When I added the theme to my repo, the site built right away. Great, finally something that worked smoothly! I showed the result to my boss and we agreed that there was a lot of hope here. I told her that I think we could get a fully-functioning POC in a week. Turned out to be a little optimistic.</p>
<p><img src="../../images/cloudify/hugo-docdock.png" alt="Hugo Docdock theme" /></p>
<p>(<a href="https://docdock.netlify.com/">DocDock Theme Site</a>)</p>
<p>Some of the challenges that I faced were:</p>
<ul>
<li>The site was not designed to be run from a subdirectory, meaning that the search mysteriously stopped working sometimes.</li>
<li>I had to figure out how to make it build in CircleCI with our dev, staging, and production build logic.</li>
<li>The site needed the company look-and-feel: header, fonts, and colors.</li>
<li>The site needed the dropdown to switch between versions.</li>
<li>I still didn’t know how to do any of it.</li>
</ul>
<h2 id="slow-progress">Slow Progress</h2>
<p>Marketing offered to help with the look-and-feel, but they were really busy with other things so I also dove into the CSS myself. I found out that the colors were specified in 3 different CSS files, so I went through them, with help from marketing, to change to the company color scheme. I switched from local fonts to online fonts based on our company website. The front-end developer in R&D helped me to create the version switching function and I figured out how to add it to the site layout files. The DevOps engineer was busy with R&D tasks but she gave me a few minutes here and there to help me get up to speed enough in git, TravisCI and CircleCI to make slow but positive progress. Of course, periodically I had to rebase and resolve conflicts and errors because, at the same time that I was working on the new structure, developers were still editing and adding content in the old structure.</p>
<p>In short, my determination to get it working and my concern about not having an alternative were my motivations. There were definitely times that I felt it was a lost cause and that I had just wasted the company’s time and money on my gut feeling that this was the right way.</p>
<p>After two (dare I say, long) months things were slowly coming together. I got the automated builds working reliably, found the KB article that resolved the search not working in a subdirectory, and got a little more time with the front-end developer to learn how to troubleshoot CSS issues and get the site to look smooth. I even came up with some little ideas of my own inspired by other knowledge bases and was able to implement those ideas.</p>
<h2 id="going-live">Going Live</h2>
<p>Release day arrived. I scheduled it on a Sunday to minimize disruption, of course, but DNS issues with AWS Route53, S3 and Cloudfront caused me to decide to rollback. Also, we didn’t make a plan for the 404 errors customers would see when going to an old link. After some more testing, I decided to go for it again first thing Wednesday morning. Because we are located in Israel, this is still a relatively acceptable time for controlled downtime.</p>
<p>I finally merged the changes from my side-branch into the master branch and things went pretty smoothly. Some tweaks were required but nothing so bad that I needed to rollback again. Unfortunately, a few more days of struggle with redirections of old URLs using AWS S3 only brought frustration. Then, I found that I could add an alias to each page so that Hugo published HTML files at the old URL locations to redirect to the new URLs. I can safely say that was the final step that brought the project to a successful conclusion.</p>
<p><img src="../../images/cloudify/new-cloudify-docs.png" alt="New Cloudify docs" /></p>
<p>(<a href="https://docs.cloudify.co/">New Cloudify Docs Site</a>)</p>
<h2 id="success-at-last">Success at last!</h2>
<p>Two weeks later I saw that unique pageviews on the site were up 50% and exit rates were down. I’m not a statistician but it looked to me like good enough statistics to show that the new site was an improvement over the old site.</p>
<p>As much as I faced lots of frustration during the process, I learned a tremendous amount and the final product was a great improvement, both as a writing process and a content delivery platform. It was a team effort to get it together, and I want to thank everyone for their help:</p>
<ul>
<li>Marketing</li>
<li>R&D</li>
<li>DevOps</li>
<li>IT</li>
<li>Product Management</li>
</ul>
<p>I hope that others can learn from the process we went through to see that it is both fun and productive to go for your dreams!</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/cloudify-dont-stop-dreaming/">Docs-as-Code: Don’t stop dreaming</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on June 05, 2018.</p>
https://www.docslikecode.com/articles/practical-advice2018-04-16T00:00:00+00:002018-04-16T00:00:00+00:00Anne Gentlehttps://www.docslikecode.com
<p>What does it take to put together a web site, a book, an ebook, all for sale online? Let’s look at costs for tools and services that make it happen.</p>
<p>Let’s look at what you need for a book idea. You need an audience, an editor, a way to reach that audience, and a “pitch” for the book idea itself. You may chose self-publishing over pitching the book idea to a technical book publisher.</p>
<p>In my recent experience with <em>Docs Like Code</em>, the process led me to choosing to produce the site, epub, and printed book all using tools I had prior experiences with. Let’s take a look.</p>
<h2 id="reaching-out-to-current-contacts">Reaching out to current contacts</h2>
<p>First, I reached out to Andy Oram, a senior editor at O’Reilly who knows me from a couple of open source projects, asking if he thought O’Reilly would want a book proposal. He said he’d be happy to read what I had, but didn’t see the initial concept fitting into their current catalog. Really great of him to offer to help out, and I simply thanked him and kept going with my idea.</p>
<p>In parallel, I reached out to the publisher for my first book, <em>Conversation and Community</em>. His name is Richard Hamilton and he runs <a href="https://xmlpress.com">XML Press</a>. When he looked at his schedule,
he couldn’t read through at the draft copy for about 3 months. Well, I thought that the timing was essential, and I didn’t want to wait that long, knowing both the market and my own availability.</p>
<h2 id="finding-like-minded-collaborators">Finding like-minded collaborators</h2>
<p>I also reached out to Diane Fleming, now Skwish, who had been teaching writers how to use Git and GitHub for docs over the same time as I had been. Over lunch, we realized we both wanted this book to be available for the next time we teach developers and writers how to write and review docs on GitHub. Diane is a talented writer and also a super editor. The best writers re-write a lot, and I knew Diane would provide an eagle eye for both technical accuracy as well as great writing.</p>
<p>Then, I realized I have a great friend in Kelly Holcomb, who edited my first book and I could talk her into editing this one, wahoo! Kelly also had experience in using GitHub for editing, so her contributions were super important for the final copy.</p>
<p>One area I did skip on for this book was a professional-level index, which Kelly was able to do for a great job on for <em>Conversation and Community</em>. I haven’t missed the index yet, and for a smaller book it seems like an index could look like padding.</p>
<h2 id="design-materials-and-promotional-work">Design materials and promotional work</h2>
<p>I also was able to do all the design imagery myself, including the book cover. This part was thanks to <a href="https://www.canva.com/">Canva</a> and some nice templates that service has online. I used the free trial for Canva to make the book cover and stickers and t-shirt design. (Updated to add: the t-shirt store cost $300/year which was not profitable so I stopped offering t-shirts in 2019.)</p>
<p>That said, I was not willing to take on the layout work myself. So, when <a href="https://www.gitbook.com/">Gitbook</a> did not output a PDF that I considered “print-ready”, I went to <a href="https://www.upwork.com">Upwork</a>. I wanted more fine-tuned layout and design for the print copy, including proper page breaks and nice tables. So I hired a designer with access to Indesign who could take the epub and turn it into a print book.</p>
<h2 id="pull-it-together">Pull it together!</h2>
<p>And so, with all those bits of input from others, it created a quest to be a product manager for my own information product! I went that route, and for me, <a href="https://www.lulu.com/">Lulu</a> was a tool I was already familiar with because we had done publishing with it for OpenStack.</p>
<p>There are other publishing options - IngramSpark, Amazon, LeanPub, and I’m sure others. I did sign up and get approved for an account with IngramSpark, which is the print-on-demand service that XML Press uses.</p>
<p>To me, after reading the <a href="https://www.lulu.com/about/our-story">origin story for Lulu</a>, I feel that Lulu is a bit more “open source” based than say, Amazon. I don’t know much about LeanPub. Since I was using Markdown on a private GitHub repo anyway, it doesn’t seem to offer more than Lulu for the marketplace reach. I’m not trying to make money at it; only trying to increase reach.</p>
<p>Finding a freelance editor would be a huge leg up on the writing process itself, especially if you also need a bit of developmental editing for the book idea.</p>
<p>For the print layout, I had a great experience with UpWork and was also able to hire the same person to work on the second edition. I learned from using a freelance site that I can find and manage freelancers for projects that I want to get done but don’t want to carve out time or buy tools for myself to finish them.</p>
<h2 id="list-of-tools-and-services">List of tools and services</h2>
<table>
<thead>
<tr>
<th>Tools</th>
<th>Site</th>
</tr>
</thead>
<tbody>
<tr>
<td>Calibre</td>
<td><a href="https://www.calibre-ebook.com/">https://www.calibre-ebook.com/</a></td>
</tr>
<tr>
<td>Canva</td>
<td><a href="https://www.canva.com/">https://www.canva.com/</a></td>
</tr>
<tr>
<td>GitBook</td>
<td><a href="https://www.gitbook.com/">https://www.gitbook.com/</a></td>
</tr>
<tr>
<td>GitHub</td>
<td><a href="https://www.github.com/">https://www.github.com/</a></td>
</tr>
<tr>
<td>Lulu</td>
<td><a href="https://www.lulu.com/">https://www.lulu.com/</a></td>
</tr>
<tr>
<td>Mailchimp</td>
<td><a href="https://www.mailchimp.com/">https://www.mailchimp.com/</a></td>
</tr>
<tr>
<td>Printful</td>
<td><a href="https://www.printful.com/">https://www.printful.com/</a></td>
</tr>
<tr>
<td>Shopify</td>
<td><a href="https://www.shopify.com/">https://www.shopify.com/</a></td>
</tr>
<tr>
<td>Upwork</td>
<td><a href="https://www.upwork.com/">https://www.upwork.com/</a></td>
</tr>
</tbody>
</table>
<h2 id="ongoing-and-startup-costs">Ongoing and startup costs</h2>
<p>Here’s a high-level overview of the startup costs for creating a book like <em>Docs Like Code</em>.
I calculated the starting costs for six or five months, when I needed a monthly subscription for a service.</p>
<table>
<thead>
<tr>
<th>Service</th>
<th>Costs</th>
</tr>
</thead>
<tbody>
<tr>
<td>Domain name registration</td>
<td>$20/year</td>
</tr>
<tr>
<td>GitHub for Private repo</td>
<td>$42 ($7/month x 6)</td>
</tr>
<tr>
<td>GitBooks for Private repo</td>
<td>$35 ($7/month x 5)</td>
</tr>
<tr>
<td>GitHub Pages for website</td>
<td>$0</td>
</tr>
<tr>
<td>Canva for Work (cover art)</td>
<td>$0 trial</td>
</tr>
<tr>
<td>Lulu (printed copies)</td>
<td>$82 for 15 printed</td>
</tr>
<tr>
<td>Editing/Writing</td>
<td>$250 celebration</td>
</tr>
<tr>
<td>Design for PDF layout</td>
<td>$250</td>
</tr>
<tr>
<td>MailChimp (ongoing)</td>
<td>$42 ($7/month x 6)</td>
</tr>
<tr>
<td>Twitter ads</td>
<td>$25 for ads</td>
</tr>
<tr>
<td>Stickers</td>
<td>$82 for 200</td>
</tr>
<tr>
<td><strong>Total startup costs</strong></td>
<td><strong>$828</strong></td>
</tr>
</tbody>
</table>
<p>Based on Lulu reporting, I see the book brought in about $2500 in 12 months of the first and second edition being available. So while the startup costs are not nothing, I did see a profit from the effort. Really, though, the effort is paid off in helping others see the benefits I’ve observed and in sharing and learning. Let me know what you think about this method, the tools, and of course, the resulting book, <em>Docs Like Code</em>.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/practical-advice/">Practical Advice On Publishing A Technical Book using GitHub and GitBook</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on April 16, 2018.</p>
https://www.docslikecode.com/articles/change-case-study2018-02-12T00:00:00+00:002018-02-12T00:00:00+00:00Tom Johnsonhttps://www.docslikecode.com
<p><strong>Originally published in the <a href="https://idratherbewriting.com/learnapidoc/pubapis_docs_as_code.html">Documenting APIs: A Guide for Technical Writers on Tom Johnson’s site, I’d Rather Be Writing</a>. Thanks, Tom, for sharing your story in detail for others to learn.</strong></p>
<p class="tip">For an overview of the docs-as-code approach, see <a href="https://idratherbewriting.com/learnapidoc/pubapis_docs_as_code.html">Docs-as-code tools</a>. In this article, I describe the challenges we faced in implementing a docs-as-code approach within a tech writing group at a large company.</p>
<p>Changing any documentation tooling at a company can be a huge undertaking. Depending on the amount of legacy content to convert, the number of writers to train, the restrictions and processes you have to work against in your corporate environment and more, it can require an immense amount of time and effort to switch tools from the status quo to docs-as-code.</p>
<p>Additionally, you will likely need to make this change outside your normal documentation work, and you’ll probably need to develop the new system <em>while still updating and publishing content in the old system</em> Essentially, this means you’ll be laying down a new highway while simultaneously driving down it.</p>
<ul id="markdown-toc">
<li><a href="#previous-processes" id="markdown-toc-previous-processes">Previous processes</a></li>
<li><a href="#advantages-of-integrating-into-a-larger-system" id="markdown-toc-advantages-of-integrating-into-a-larger-system">Advantages of integrating into a larger system</a></li>
<li><a href="#end-solution" id="markdown-toc-end-solution">End solution</a></li>
<li><a href="#challenges-we-faced" id="markdown-toc-challenges-we-faced">Challenges we faced</a></li>
<li><a href="#creative-solutions-for-theme-distribution-across-repos" id="markdown-toc-creative-solutions-for-theme-distribution-across-repos">Creative solutions for theme distribution across repos</a></li>
<li><a href="#ensuring-everyone-builds-with-the-same-version-of-jekyll" id="markdown-toc-ensuring-everyone-builds-with-the-same-version-of-jekyll">Ensuring everyone builds with the same version of Jekyll</a></li>
<li><a href="#figuring-out-translation-workflows" id="markdown-toc-figuring-out-translation-workflows">Figuring out translation workflows</a></li>
<li><a href="#other-challenges" id="markdown-toc-other-challenges">Other challenges</a></li>
<li><a href="#conclusion" id="markdown-toc-conclusion">Conclusion</a></li>
<li><a href="#blog-posts-about-docs-as-code-tools" id="markdown-toc-blog-posts-about-docs-as-code-tools">Blog posts about docs-as-code tools</a></li>
</ul>
<h2 id="previous-processes">Previous processes</h2>
<p>Previously, our team published content through a content management system called <a href="https://www.bloomreach.com/en/products/experience/hippo-cms">Hippo</a> (by Bloomreach). Hippo is similar to WordPress or Drupal but is Java-based rather than PHP-based (which made it attractive to a Java-centric enterprise that restricted PHP but still needed a CMS solution for publishing).</p>
<p>To publish a page of documentation, tech writers had to create a new page in the Hippo CMS and then paste in the HTML for the page (or try to use the WYSIWYG editor in the Hippo CMS). If you had 50 pages of documentation to publish, you would need to paste the HTML into each CMS page one by one. Originally, many writers would use tools such as <a href="https://pandoc.org/">Pandoc</a> to convert their content to HTML and then paste it into the Hippo CMS. This copy-and-paste approach was tedious, prone to error, and primitive.</p>
<p>When I started, I championed using Jekyll to generate and manage the HTML, and I started storing the Jekyll projects in internal Git repositories. I also created a layout in Jekyll that was designed specifically for Hippo publishing. The layout included a documentation-specific sidebar (previously absent in Hippo on a granular level) to navigate all the content in a particular set of documentation. This Jekyll layout included a number of styles and scripts to override settings in the CMS.</p>
<p>Despite this innovation, our publishing process still involved pasting the generated HTML (after building Jekyll) page by page into the CMS. Thus, we were halfway with our docs-as-code approach and still had room to go. One of the tenets of docs-as-code is to build your output directly from the server (called “continuous deployment”). In other words, you incorporate the publishing logic on the server rather than running the publishing process from your local computer.</p>
<p>This last step, publishing directly from the server, was difficult because another engineering group was responsible for the website and server, and we couldn’t just rip Hippo out and start uploading the Jekyll-generated files onto a web server ourselves. It would take another year or more before the engineering team had the bandwidth for the project. Once it started, the project was a wild ride of mismatched expectations and assumptions. But in the end, we succeeded.</p>
<p>Most of the lessons learned here are about this process, specifically how we transitioned to building Jekyll directly from an internal Git repo, the decisions we made and the reasoning behind those decisions, the compromises and other changes of direction, and so on. My purpose here is to share lessons learned so that other writers embarking on similar endeavors can benefit from understanding what might be on the road ahead.</p>
<h2 id="advantages-of-integrating-into-a-larger-system">Advantages of integrating into a larger system</h2>
<p>Why did we want to move to docs as code in the first place? At most large companies, there are plenty of robust, internally developed tools that tech writers can take advantage of. The docs-as-code approach would allow us to integrate into this robust enterprise infrastructure that developers had already created.</p>
<p>Documentation tools are often independent, standalone tools that offer complete functionality (such as version control, search, and deployment) within their own system. But these systems are often a black box, meaning, you can’t really open them up and integrate them into another process or system. With the docs-as-code approach, we had the flexibility to adapt our process to fully integrate within the company’s infrastructure and website deployment process. Some of this infrastructure we wanted to hook into included the following:</p>
<ul>
<li>Internal test environments (a gamma environment separate from production)</li>
<li>Authentication for specific pages based on account profiles</li>
<li>Search and indexing</li>
<li>Website templating (primarily a complex header and footer)</li>
<li>Robust analytics</li>
<li>Secure servers in order to satisfy Information Security policies with the corporate domain</li>
<li>Media CDN for distributing images</li>
<li>Git repositories and GUI for managing code</li>
<li>Build pipelines and a build management system</li>
</ul>
<p>All we really needed to do was to generate out the body HTML along with the sidebar and make it available for the existing infrastructure to consume. The engineering team that supported the website already had a process in place for managing and deploying content on the site. We wanted to use similar processes rather than coming up with an entirely different approach.</p>
<h2 id="end-solution">End solution</h2>
<p>In the end, here’s the solution we implemented. We stored our Jekyll project in an internal Git repository — the same farm of Git repositories other engineers used for nearly every software project, and which connected into a build management system. After we pushed our Jekyll doc content to the master branch of the Git repository, a build pipeline would kick off and build the Jekyll project directly from the server (similar to <a href="https://pages.github.com/">GitHub Pages</a>).</p>
<p>Our Jekyll layout omitted any header or footer in the theme. The built HTML pages were then pulled into an S3 bucket in AWS through an ingestion tool (which would check for titles, descriptions, and unique permalinks in the HTML). This bucket acted as a flat-file database for storing content. Our website would make calls to the content in S3 based on permalink values in the HTML to pull the content into a larger website template that included the header and footer.</p>
<p>The build process from the Git repo to the deployed website took about 10 minutes, but tech writers didn’t need to do anything during that time. After you typed a few commands in your terminal (merging with the <code class="language-plaintext highlighter-rouge">gamma</code> or <code class="language-plaintext highlighter-rouge">production</code> branch locally and then pushing out the update to origin), the deployment process kicked off and ran all by itself.</p>
<p>The first day in launching our new system, a team had to publish 40 new pages of documentation. Had we still been in Hippo, this would have taken several hours. Even more painful, their release timeframe was an early morning, pre-dawn hour, so the team would have had to publish 40 pages in Hippo CMS at around 4 am to 6 am, copying and pasting the HTML frantically to meet the release push and hoping they didn’t screw anything up.</p>
<p>Instead, with the new process, the writer just merged her development branch into the <code class="language-plaintext highlighter-rouge">production</code> branch and pushed the update to the repo. Ten minutes later, all 40 pages were live on the site. She was floored! We knew this was the beginning of a new chapter in our team’s processes. We felt like a huge burden had been lifted off our shoulders, and the tech writers loved the new system.</p>
<h2 id="challenges-we-faced">Challenges we faced</h2>
<p>I’ve summarized the success and overall approach, but there were a lot of questions and hurdles in developing the process. I’ll detail these main challenges in the following sections.</p>
<h3 id="inability-to-do-it-ourselves">Inability to do it ourselves</h3>
<p>The biggest challenge, ironically, was probably with myself — dealing with my own perfectionist, controlling tendencies to do everything on my own, just how I wanted. (This is probably both my biggest weakness and strength as a technical writer.) It’s hard for me to relinquish control and have another team do the work. We had to wait <em>about a year</em> for the overworked engineering team’s schedule to clear up so they would have the bandwidth to do the project.</p>
<p>During this wait time, we refined our Jekyll theme and process, ramped up on our Git skills, and migrated all of the content out of the old CMS into <a href="https://kramdown.gettalong.org/">kramdown Markdown</a>. Even so, as project timelines kept getting delayed and pushed out, we weren’t sure if the engineering team’s bandwidth would ever lighten up. I wanted to jump ship and just deploy everything myself through the <a href="https://github.com/laurilehmijoki/s3_website">S3_website plugin</a> on <a href="https://aws.amazon.com/s3/">AWS S3</a>.</p>
<p>But as I researched domain policies, server requirements, and other corporate standards and workflows, I realized that a do-it-myself approach wouldn’t work (unless I possessed a lot more engineering knowledge than I currently did). Given our corporate domain, security policies required us to host the content on an internal tier 1 server, which had to pass security requirements and other standards. It became clear that this would involve a lot more engineering knowledge and time than I had, as well as maintenance time if I managed the server post-release, so we had to wait.</p>
<p>We wanted to get this right because we probably wouldn’t get bandwidth from the engineering team again for a few years. In the end, waiting turned out to be the right approach.</p>
<h3 id="understanding-each-other">Understanding each other</h3>
<p>When we did finally begin the project and started working with the engineering team, another challenge was in understanding each other. The engineering team (the ones implementing the server build pipeline and workflow) didn’t understand our Jekyll authoring process and needs.</p>
<p>Conversely, we didn’t understand the engineer’s world well either. To me, it seemed all they needed to do was upload HTML files to a web server, which seemed a simple task. I felt they were overcomplicating the process with unnecessary workflows and layouts. And what was the deal with storing content in S3 and doing dynamic lookups based on matching permalinks? But whereas I had in mind a doghouse, they had in mind a skyscraper. So their processes were probably more or less scaled and scoped to the business needs and requirements.</p>
<p>Still, we lived in different worlds, and we had to constantly communicate about what each other needed. It didn’t help that we were located in different states and had to interact virtually, often through chat and email.</p>
<h3 id="figuring-out-repo-size">Figuring out repo size</h3>
<p>Probably the main challenge was to figure out the correct size for the documentation repos. Across our teams, we had 30 different products, each with their doc navigation and content. Was it better to store each product in its own repo, or to store all products in one giant repo? I flipped my thinking on this several times.</p>
<p>Storing content in multiple repos led to quick build times, reduced visual clutter, resulted in fewer merge conflicts, didn’t introduce warnings about repo sizes, and had other benefits with autonomy.</p>
<p>On the other hand, storing all content in one repo simplified content re-use, made link management and validation easier, reduced maintenance efforts, and more. Most of all, it made it easier to update the theme in a single place rather than duplicating theme file updates across multiple repos.</p>
<p>Originally, our team started out storing content in separate repos. When I had updates to the Jekyll theme, I thought I could simply explain what files needed to be modified, and each tech writer would make the update to their theme’s files. This turned out not to really work — tech writers didn’t like making updates to theme files. The Jekyll projects became out of date, and then when someone experienced an issue, I had no idea what version of the theme they were on.</p>
<p>I then championed consolidating all content in the same repo. We migrated all of these separate, autonomous repos into one master repo. This worked well for making theme updates. But soon the long build times (1-2 minutes for each build) became painful. We also ran into size warnings in our repo (images and other binary files such as Word docs were included in the repos). Sometimes merge conflicts happened.</p>
<p>The long build times were so annoying, we decided to switch back to individual repos. There’s nothing worse than waiting 2 minutes for your project to build, and I didn’t want the other tech writers to hate Jekyll like they did Hippo. The lightning-fast auto-regenerating build time with Jekyll is part of its magic.</p>
<h2 id="creative-solutions-for-theme-distribution-across-repos">Creative solutions for theme distribution across repos</h2>
<p>I came up with several creative ways to push the theme files out to multiple small repos in a semi-automated way. My first solution was to distribute the theme through <a href="https://rubygems.org/">RubyGems</a>, which is Jekyll’s official <a href="https://jekyllrb.com/docs/themes/">solution for theming</a>. I created a theme gem, open-sourced it and the theme (see <a href="https://github.com/amzn/jekyll-doc-project">Jekyll Doc Project</a>), and practiced the workflow to push out updates to the theme gem and pull them into each repo.</p>
<p>It worked well (just as designed). However, it turns out our build management system (an engineering tool used to build outputs or other artifacts from code repositories) couldn’t build Jekyll from the server using <a href="https://bundler.io/">Bundler</a>, which is what RubyGems required. (Bundler is a tool that automatically gets the right gems for your Jekyll project based on the Jekyll version you are using. Without Bundler, each writer just installs the <a href="https://rubygems.org/gems/jekyll/versions/3.3.1">jekyll gem</a> locally and builds the Jekyll project based on that gem version.</p>
<p>My understanding of the build management system was limited, so I had to rely on engineers for their assessment. Ultimately, we had to scrap using Bundler and just build using <code class="language-plaintext highlighter-rouge">jekyll serve</code>. I still had the problem of distributing the same theme across multiple repos.</p>
<p>My second attempt was to distribute the theme through <a href="https://git-scm.com/book/en/v2/Git-Tools-Submodules">Git submodules</a>. This involved storing the theme in its own Git repo that other Git repos would pull in. However, our build management system couldn’t support Git submodules either, it turned out.</p>
<p>I then came up with a way to distribute the theme through <a href="https://www.atlassian.com/blog/git/alternatives-to-git-submodule-git-subtree">Git subtrees</a>. Git subtrees worked in our build system (although the commands were strange), and it preserved the short build times. However, when the engineering team started counting up all the separate build pipelines they’d have to create and maintain for each of these separate repos (around 30), they said this wasn’t a good idea from a maintenance point of view.</p>
<p>Not understanding all the work involved around building publishing pipelines for each Git repo, there was quite a bit of frustration here. It seemed like I was going out of my way to accommodate engineering limitations, and I wasn’t sure if they were modifying any of their processes to accommodate us. But eventually, we settled on two Git repos and two pipelines. We had to reconsolidate all of our separate repos back into two repos. You can probably guess that moving around all of this content, splitting it out into separate repos and then re-integrating it back into consolidated repos, etc., wasn’t a task that the writers welcomed.</p>
<p>There was a lot of content and repo adjustment, but in the end, two large repos was the right decision. In fact, in retrospect, I wouldn’t have minded just having one repo for everything.</p>
<p>Each repo had its own Jekyll project. If I had an update to any theme files (e.g., layouts or includes), I copied the update manually into both repos. This was easier than trying to devise an automated method. It also allowed me to test updates in one repo before rolling them out to the other repo. To reduce the slow build times, I created project-specific config files that would cascade with the default configuration file and build only one directory rather than all of them. This reduced the build time to the normal lightning-fast times of less than 5 seconds.</p>
<p>More specifically, to reduce the build times, we created a project-specific configuration file (e.g., acme-config.yml) that sets, through the <code class="language-plaintext highlighter-rouge">defaults</code>, all the directories to <code class="language-plaintext highlighter-rouge">publish: false</code> but lists one particular directory (the one with content you’re working on) as <code class="language-plaintext highlighter-rouge">publish: true</code>. Then to build Jekyll, you cascade the config files like this:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>jekyll serve <span class="nt">--config</span> _config.yml,acme-config.yml
</code></pre></div></div>
<p>The config files on the right overwrite the config files on the left. It works quite well.</p>
<p>Also, although at the time I grumbled about having to consolidate all content into two repos, I realized it was the right decision. Recognizing this, my respect and trust in the engineering team’s judgment grew considerably. In the future, I started to treat the engineers’ recommendations and advice about various processes with much more respect. I didn’t assume they misunderstood our authoring needs and requirements so much, and instead followed their direction more readily.</p>
<h2 id="ensuring-everyone-builds-with-the-same-version-of-jekyll">Ensuring everyone builds with the same version of Jekyll</h2>
<p>Another challenge was ensuring everyone built the project using the same version of Jekyll. Normally, you include a Gemfile in your Jekyll project that specifies the version of Jekyll you’re using, and then everyone who builds the project with this Gemfile runs Bundler to make sure the project executes with this version of Jekyll. However, since our build pipeline had trouble running Bundler, we couldn’t ensure that everyone was running the same version of Jekyll.</p>
<p>Ideally, you want everyone on the team using the same version of Jekyll to build their projects, and you want this version to match the version of Jekyll used on the server. Otherwise, Jekyll might not build the same way. You don’t want to later discover that some lists don’t render correctly or that some code samples don’t highlight correctly because of a mismatch of gems. Without Bundler, everyone’s version of Jekyll probably differed. Additionally, the latest supported version of Jekyll in the build management system was an older version of Jekyll (at the time, it was 3.4.3, which had a dependency on an earlier version of Liquid that was considerably slower in building out the Jekyll site).</p>
<p>The engineers finally upgraded to Jekyll 3.5.2, which allowed us to leverage Liquid 4.0. This reduced the build time from about 5 minutes to 1.5 minutes. Still, Jekyll 3.5.2 had a dependency on an older version of the <a href="https://rubygems.org/gems/rouge">rouge gem</a>, which was giving us issues with some code syntax highlighting for JSON. The process of updating the gem within the build management system was foreign territory to me, and it was also a new process for the engineers.</p>
<p>To keep everyone in sync, we asked that each writer check their version of Jekyll and manually upgrade to the latest version. This turned out not to be much of an issue since there wasn’t much of a difference from one Jekyll gem version to the next (at least for the features we were using).</p>
<p>Ultimately, I learned that it’s one thing to update all the Jekyll gems and other dependencies on your own machine, but it’s an entirely different effort to update these gems within a build management server in an engineering environment you don’t own.</p>
<h2 id="figuring-out-translation-workflows">Figuring out translation workflows</h2>
<p>Figuring out the right process for translation was also difficult. We started out translating the Markdown source. Our translation vendor affirmed they could handle Markdown as a source format, and we did tests to confirm it. However, after a few translation projects, it turned out that they couldn’t handle content that <em>mixed</em> Markdown with HTML, such as a Markdown document with an HTML table (and we almost always used HTML tables in Markdown). The vendors would count each HTML element as a Markdown entity, which would balloon the cost estimates.</p>
<p>Further, the number of translation vendors that could handle Markdown was limited, which created risks around the vendors that could even be used. For example, our localization managers often wanted to work with translation agencies in their own time zones. But if we were reliant on a particular vendor for their ability to process Markdown, we restricted our flexibility with vendors. If we wanted to scale across engineering, we couldn’t force every team to use the same translation vendors, which might not be available in the right time zones. Eventually, we decided to revert to sending only HTML to vendors.</p>
<p>However, if we sent only the HTML output from Jekyll to vendors, it made it difficult to apply updates. With Jekyll (and most static site generators), your sidebar and layout are packaged into <em>each</em> of your individual doc pages. Assuming that you’re just working with the HTML output (not the Markdown source), if you have to add a new page to your sidebar, or update any aspect of your layout, you would need to edit each individual HTML file instance to make those updates across the documentation. That wasn’t something we wanted to do.</p>
<p>In the end, the process we developed for handling translation content involved manually inserting the translated HTML into pages in the Jekyll project and then having these pages build into the output like the other Markdown pages. We later evolved the process to create container files that provided the needed frontmatter metadata but which used includes to pull the body content from the returned HTML file supplied by the translation vendors. It was a bit of manual labor, but acceptable given that we didn’t route content through translation all that often.</p>
<p>The URLs for translated content also needed to have a different <code class="language-plaintext highlighter-rouge">baseurl</code>. Rather than outputting content in the <code class="language-plaintext highlighter-rouge">/docs/</code> folder, translated content needed to be output into <code class="language-plaintext highlighter-rouge">/ja/docs/</code> (for Japanese) or <code class="language-plaintext highlighter-rouge">/de/docs/</code> (for German). However, a single Jekyll project can have only one <code class="language-plaintext highlighter-rouge">baseurl</code> value as defined in the default _config.yml file. I had this <code class="language-plaintext highlighter-rouge">baseurl</code> value automated in a number of places in the theme.</p>
<p>To account for the new <code class="language-plaintext highlighter-rouge">baseurl</code>, I had to incorporate a number of hacks to prepend language prefixes into this path and adjust the permalink settings in each translated sidebar to build the file into the right <code class="language-plaintext highlighter-rouge">ja</code> or <code class="language-plaintext highlighter-rouge">de</code> directory in the output. It was confusing and if something breaks in the future, it will take me a while to unravel the logic I implemented.</p>
<p>Overall, translation remains one of the trickier aspects to handle with static site generators, as these tools are rarely designed with translation in mind. But we made it work. (Another challenge with translation was how to handle partially translated doc sets — I won’t even get into this here.)</p>
<p>Overall, given the extreme flexibility and open nature of static site generators, we were able to adapt to the translation requirements and needs on the site.</p>
<h2 id="other-challenges">Other challenges</h2>
<p>There were a handful of other challenges worth mentioning (but not worth full development as in the previous sections). I’ll briefly list them here so you know what you might be getting into when adopting a docs-as-code approach.</p>
<h3 id="moving-content-out-of-the-legacy-cms">Moving content out of the legacy CMS</h3>
<p>We probably had about 1,500 pages of documentation between our 10 writers. Moving all of this content out of the old CMS was challenging. Additionally, we decided to leave some deprecated content in the CMS, as it wasn’t worth migrating. Creating redirect scripts that would correctly re-route all the content to the new URLs (especially with changed file names) while not routing away from the deprecated CMS pages was challenging. Engineers wanted to handle these redirects at the server level, but they needed a list of old URLs and new URLs.</p>
<p>To programmatically create redirect entries for all the pages, I created a script that iterated throughout each doc sidebar and generated out a list of old and new URLs in a JSON format that the engineering team could incorporate into their redirect tool. It worked pretty well, but migrating the URLs through comprehensive redirects required more analysis and work.</p>
<h3 id="implementing-new-processes-while-still-supporting-the-old">Implementing new processes while still supporting the old</h3>
<p>While our new process was in development (and not yet rolled out), we had to continue supporting the ability for writers to generate outputs for the old system (pasting content page by page into the legacy Hippo CMS). Any change we made had to also include the older logic and layouts to support the older system. This was particularly difficult with translation content since it required such a different workflow. Being able to migrate our content into a new system while continuing to publish in the older system, without making updates in both places, was a testament to the flexibility of Jekyll. We created separate layouts and configuration files in Jekyll to facilitate these needs.</p>
<p>One of the biggest hacks was with links. Hippo CMS required links to be absolute links if pasting HTML directly into the code view rather than using the WYSIWYG editor (insane as this sounds, it’s true). We created a script in our Jekyll project to populate links with either absolute or relative URLs based on the publishing targets. It was a non-standard way of doing links (essentially we treated them as variables whose value was defined through properties in the config file). It worked. Again, Jekyll’s flexibility allowed us to engineer the needed solution.</p>
<h3 id="constantly-changing-the-processes-for-documentation">Constantly changing the processes for documentation</h3>
<p>We had to constantly change the processes for documentation to fit what did or did not work with the engineering processes and environment. For example, git submodules, subtrees, small repos, large repos, frontmatter, file names, translation processes, etc., all fluctuated as we finalized the process and worked around issues or incompatibilities.</p>
<p>Each change created some frustration and stress for the tech writers, who felt that processes were changing too much and didn’t like to hear about updates they would need to make or learn. And yet, it was hard to know the end from the beginning, especially when working with unknowns around engineering constraints and requirements. Knowing that the processes we were laying down now would likely be cemented into the pipeline build and workflow for long into the distant future was stressful.</p>
<p>I wanted to make sure we got things right, which might mean adjusting our process, but I didn’t want to do that too much adjustment because each time there was a change, it weakened the confidence among the other tech writers about our direction and expertise about what we were doing.</p>
<p>During one meeting, I somewhat whimsically mentioned that updating our permalink path wouldn’t be a bad idea (to have hierarchy in the URLs). One of the tech writers noted that she was already under the gun to meet deadlines for four separate projects and wasn’t inclined to update all the permalinks for each page in these projects. After that, I was cautious about introducing any change without having an extremely compelling reason for it.</p>
<p>The experience made me realize that the majority of tech writers don’t like to tinker around with tools or experiment with new authoring approaches. They’ve learned a way to write and publish content, and they resent it when you modify that process. It creates an extreme amount of stress in their lives. And yet, I kind of liked to try new approaches and techniques.</p>
<p>In the the engineering camp, I also took some flak for changing directions too frequently. I had to change directions to try to match the obscure engineering requirements. In retrospect, it would have helped if I had visited the engineers for a week to learn their workflow and infrastructure in depth.</p>
<h3 id="styling-the-tech-docs-within-a-larger-site">Styling the tech docs within a larger site</h3>
<p>Another challenge was with tech doc styles. The engineering team didn’t have resources to handle our tech doc styling, so I ended up creating a stylesheet (3,000 lines long) with all CSS namespaced to a class of <code class="language-plaintext highlighter-rouge">docs</code> (for example, <code class="language-plaintext highlighter-rouge">.docs p, .docs ul</code>, etc). I implemented namespacing to ensure the styles wouldn’t alter other components of the site. Much of this CSS I simply copied from <a href="https://getbootstrap.com/">Bootstrap</a>. The engineers pretty much incorporated this stylesheet into their other styles for the website.</p>
<p>With JavaScript, however, we ran into namespace collisions and had to wrap our jQuery functions in a special name to avoid conflicts (the conflicts would end up breaking the initialization of some jQuery scripts). These namespace collisions with the scripts weren’t apparent locally and were only visible after deploying on the server, so the test environment constantly flipped between breaking or not breaking the sidebar (which used jQuery). As a result, seeing broken components created a sense of panic from the engineers and dread among the tech writers.</p>
<p>The engineers weren’t happy that we had the ability to break the display of content with our layout code in Jekyll. At the same time, we wanted the ability to push out content that relied on jQuery or other scripts. In the end, we got it to work, and the returned stability calmed down the writers.</p>
<h3 id="transitioning-to-a-git-based-workflow">Transitioning to a git-based workflow</h3>
<p>While it may seem like Jekyll was the authoring tool to learn, actually the greater challenge was becoming familiar with Git-based workflows for doc content. This required some learning and familiarity with the command line and version control workflows.</p>
<p>Some writers already had a background with Git, while others had to learn it. Although we all ended up learning the Git commands, I’m not sure everyone actually used the same processes for pulling, pushing, and merging content (there’s a lot of ways to do similar tasks).</p>
<p>There were plenty of times where someone accidentally merged a development branch into the master or found that two branches wouldn’t merge, or they had to remove content from the master and put it back into development, etc. Figuring out the right process in Git is not a trivial undertaking. Even now, I’ll occasionally find a formatting error because Git’s conflict markers <code class="language-plaintext highlighter-rouge">>>>>>>></code> and <code class="language-plaintext highlighter-rouge"><<<<<<<</code> find their way into the content, presumably from a merge gone wrong. We don’t have any validation scripts (yet) that look for marker stubs like this, so it’s a bit disheartening to suddenly come across them.</p>
<h3 id="striking-a-balance-between-simplicity-and-robustness-in-doc-tooling">Striking a balance between simplicity and robustness in doc tooling.</h3>
<p>Overall, we had to support a nearly impossible requirement in accommodating less technical contributors (such as project managers or administrators outside our team). The requirement was to keep doc processes simple enough for non-technical people to make updates (similar to how they did in the old CMS), while also providing enough robustness in the doc tooling to satisfy the needs of tech writers, who often need to single-source content, implement variables, re-use snippets, output to PDF, and more.</p>
<p>In the end, given that our main audience and contributors were developers, we favored tools and workflows that developers would be familiar with. To contribute substantially in the docs, we decided that you would have to understand, to some extent, Git, Markdown, and Jekyll. For non-technical users, we directed them to a GUI (similar to GitHub’s GUI) they could interact with to make edits in the repository. Then we would merge in and deploy their changes.</p>
<p>However, even the less technical users eventually learned to clone the project and push their updates into a development branch using the command line. It seems that editing via the GUI is rarely workable as a long-term solution.</p>
<h3 id="building-a-system-that-scales">Building a system that scales</h3>
<p>Although we were using open source tools, our solution had to be able to scale in an enterprise way. Because the content used Markdown as the format, anyone could easily learn it. And because we used standard Git processes and tooling, engineers can more easily plug into the system.</p>
<p>We already had some engineering teams interacting in the repo. Our goal was to empower lots of engineering teams with the ability to plug into this system and begin authoring. Ideally, we could have dozens of different engineering groups owning and contributing content, with the tech writers acting more like facilitators and editors.</p>
<p>Also significant is that no licenses or seats were required to scale out the authoring. A writer just uses Atom editor (or another IDE). The writer would open up the project and work with the text, treating docs like code.</p>
<p>Within the first few weeks of launching our system, we found that engineers liked to contribute updates using the same code review tools they used with software projects. This simplified the editing workflow. But it also created more learning on our part, because it meant we would need to learn these code review tools, how to push to the code review system, how to merge updates from the reviews, and so forth.</p>
<p>Additionally, empowering these other groups to author required us to create extensive instructions, which was an entire documentation project in itself. I created around 30+ topics in our guide that explained everything from setting up a new project to publishing from the command line using Git to creating PDFs, navtabs, inserting tooltips and more. Given that this documentation was used internally only and wasn’t documentation consumed externally, there wasn’t a huge value or time allotment for creating it. Yet it consumed <em>a lot</em> of time. Making good documentation is hard, and given the questions and onboarding challenges, I realized just how much the content needed to be simplified and easier to follow.</p>
<h2 id="conclusion">Conclusion</h2>
<p>Almost everyone on the team was happy about the way our doc solution turned out. Of course, there are always areas for improvement, but the existing solution was head and shoulders above the previous processes. Perhaps most importantly, Jekyll gave us an incredible degree of flexibility to create and adapt to our needs. It was a solution we could build on and make fit our infrastructure and requirements.</p>
<p>I outlined the challenges here to reinforce the fact that implementing docs-as-code is no small undertaking. It doesn’t have to be an endeavor that takes months, but at a large company, if you’re integrating with engineering infrastructure and building out a process that will scale and grow, it can require a decent amount of engineering expertise and effort.</p>
<p>If you’re implementing docs-as-code at a small company, you can simplify processes and use a system that meets your needs. For example, you could simply use <a href="https://pages.github.com/">GitHub Pages</a>, or use the <a href="https://github.com/laurilehmijoki/s3_website">S3_website plugin</a> to publish on AWS S3, or better yet, use a continuous deployment platform like <a href="https://cloudcannon.com/">CloudCannon</a> or <a href="https://www.netlify.com/">Netlify</a>. (I explore these tools in more depth here: <a href="https://idratherbewriting.com/learnapidoc/pubapis_docs_as_code.html">Publishing tool options for developer docs</a>.) I might have opted for either of these approaches if allowed and if we didn’t have an engineering support team to implement the workflow I described.</p>
<h2 id="blog-posts-about-docs-as-code-tools">Blog posts about docs-as-code tools</h2>
<p>To read some other docs-as-code posts on my blog, see the following:</p>
<ul>
<li><a href="https://idratherbewriting.com/2017/08/23/content-architecture-and-repo-sizes/">Discoveries and realizations while walking down the Docs-as-Code path</a></li>
<li><a href="https://idratherbewriting.com/2017/06/02/when-docs-are-not-like-code/">Limits to the idea of treating docs as code</a></li>
<li><a href="https://idratherbewriting.com/2016/08/01/responding-to-feedback-on-modern-tech-writing-review/">Will the docs-as-code approach scale? Responding to comments on my Review of Modern Technical Writing</a></li>
</ul>
<p class="tip">To Learn more about docs as code, see Anne Gentle’s book <a href="https://www.amazon.com/Docs-Like-Code-Anne-Gentle/dp/1365816079/ref=sr_1_1?ie=UTF8&qid=1508090523&sr=8-1&keywords=docs+like+code">Docs Like Code</a>.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/change-case-study/">Case study: Switching tools to docs-as-code</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on February 12, 2018.</p>
https://www.docslikecode.com/articles/video-presentations-docs-like-code2018-01-06T00:00:00+00:002018-01-06T00:00:00+00:00Anne Gentlehttps://www.docslikecode.com
<p>In the new year I want to keep learning more about docs like code, and I know that I’ve learned a lot from the Write the Docs community and presentations.</p>
<p>Top of mind for me right now is that the 2018 conference in Portland Oregon is in May, 6-8 to be exact, and the <a href="https://www.writethedocs.org/conf/portland/2018/cfp/">call for proposals closes next Wednesday</a>, January 10, 2018. You can register and buy your ticket - or tickets for your whole team - <a href="https://www.writethedocs.org/conf/portland/2018/">online now</a>.</p>
<p>Even when I don’t make it to the conference in person, the video recordings are super helpful to learn from others. Here’s a collection of the relevant talks over the years:</p>
<h3 id="2017-us-conference">2017 US conference</h3>
<p><a href="https://www.youtube.com/watch?v=Mzu-c-FoOdw">Jodie Putrino</a> presented “Treating documentation like code: a practical account” to share her experiences at F5 Networks.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Mzu-c-FoOdw" frameborder="0" allowfullscreen=""></iframe>
<h3 id="2016-us-conference">2016 US conference</h3>
<p><a href="https://www.youtube.com/watch?v=Y2TGwUPb8R4">A panel</a> of folks from Rackspace, Microsoft, Balsamiq, and Twitter talked about how they are adopting these practices.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/Y2TGwUPb8R4" frameborder="0" allowfullscreen=""></iframe>
<h3 id="2016-eu-conference">2016 EU conference</h3>
<p><a href="https://www.youtube.com/watch?v=JvRd7MmAxPw">Margaret Eker and Jennifer Roundeau</a> talked about the “Missing Manual” for docs like code.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/JvRd7MmAxPw" frameborder="0" allowfullscreen=""></iframe>
<p><a href="https://www.youtube.com/watch?v=dHdBsNxtKeI">Rachel Whitten</a> talked about docs-as-code in practice.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/dHdBsNxtKeI" frameborder="0" allowfullscreen=""></iframe>
<h3 id="2015-us-conference">2015 US conference</h3>
<p><a href="https://www.youtube.com/watch?v=EnB8GtPuauw">Riona MacNamara</a> spoke about how adopting docs like code has completely transformed how Google does documentation.</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/EnB8GtPuauw" frameborder="0" allowfullscreen=""></iframe>
<p>All this to say, the docs-like-code concepts are widely practiced in our industry, and each conference provides more inspiring examples. Perhaps you can watch these presentations and be inspired to integrate code and doc techniques.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/video-presentations-docs-like-code/">Video Presentations about Docs Like Code</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on January 06, 2018.</p>
https://www.docslikecode.com/articles/rackspace-case-study2017-11-12T00:00:00+00:002017-11-12T00:00:00+00:00Margaret Ekerhttps://www.docslikecode.com
<p>At Rackspace, we recently modernized our customer documentation, implementing a model that treats documents like code.</p>
<p>Known in the tech industry as “docs like code” or “docs as code,” the model provides self-service test, build and web publishing capabilities enabling Rackers and customers to write collaboratively.</p>
<p>The transformation has been a measurable success. The number of contributors has skyrocketed, from 6 to 175, we’ve reduced content build and deployment time from minutes to seconds and eliminated manual review processes by providing web-based staging environments everyone can access.</p>
<p>We now have a modern, responsive user interface with multi-platform support accessible on standard and mobile platforms. We swapped out a custom authoring environment that relied on licensed tools and a specialized support team with open source development tools that can be maintained collaboratively by writing and development teams.</p>
<p>Completing the project took two years. During that time, similar projects at organizations like <a href="https://www.youtube.com/watch?v=6y4eQ6gYwdU&index=1&list=PLmV2D6sIiX3UkFCMqq5at0xYgsMqAr6Jf">Twitter</a>, <a href="https://www.youtube.com/watch?v=EnB8GtPuauw&list=PLmV2D6sIiX3UW1kPWlhzyo4lr6e3US6re&index=14">Google</a> and the <a href="https://opensource.com/business/15/4/git-and-github-open-source-documentation-reviews">OpenStack Foundation</a> inspired us.</p>
<p>Each story reflected the unique culture, development environment and goals of the organization, but we found value in the different perspectives, common challenges and cautionary tales that eased our journey.</p>
<p>I want to add another perspective to these stories based on my experience as a senior information developer at Rackspace, and describe how Rackers and customers use the new platform, and the challenges we’ve overcome.</p>
<h2 id="what-is-docs-like-code">What is docs like code?</h2>
<p>In <a href="https://www.amazon.com/Modern-Technical-Writing-Introduction-Documentation-ebook/dp/B01A2QL9SS?tag=viglink124746-20">Modern Technical Writing</a>, <a href="https://www.linkedin.com/in/andrew-etter-0a013349">Andrew Etter</a> describes a docs like code model that uses plain text formats and code systems to deliver documentation. Content source is stored in repositories using version control services like GitHub and BitBucket. Another key component is a continuous integration and delivery, or CI/CD system that supports automated web-delivery of content.</p>
<p>A docs like code system enables all teams to contribute content. It simplifies platform development and maintenance by eliminating custom authoring and publishing systems in favor of a unified system for docs and code. Collaboration is easier because everyone works in the same environment.</p>
<p>In a docs like code world, everyone has more time to write. People with technical expertise can write content, which increases the chances that the documentation matches the code and keeps pace with product updates and changes. People with writing expertise can focus on strategic activities like information architecture and content strategy, curation and testing. Most importantly, an effective docs like code implementation enables shared ownership of the content so everyone has a stake in its quality and how effectively it meets customer needs.</p>
<p><img src="../../images/democratize-your-content.png" alt="Democratize Your Content" /></p>
<h2 id="how-its-working-at-rackspace">How it’s working at Rackspace</h2>
<p>The Rackspace documentation platform delivers to our <a href="https://support.rackspace.com/how-to/?_ga=2.229160092.1251205099.1509294907-568023077.1505957457">Support Network How-To</a> repository, Carina and <a href="https://developer.rackspace.com/docs/?_ga=2.198884143.1251205099.1509294907-568023077.1505957457">Rackspace developer</a> websites. Depending on the website, contributors deliver content in <a href="https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet#lists">Markdown</a> and <a href="https://docutils.sourceforge.net/rst.html">reStructuredText</a> format.</p>
<p>We use GitHub and GitHub workflow to manage source as well as content development and review. Our <a href="https://github.com/deconst">custom-built documentation platform</a> assembles documentation from individual GitHub source repositories and publishes it to the web. The platform supports content created using the Jekyll static site generator and Sphinx documentation generator, and can be extended to support other content development frameworks.</p>
<p>Customers can propose changes or submit feedback by using the Edit on GitHub and Submit issue on the documentation user interface.</p>
<p>We also provide instructions, training and templates to enable internal contributions from Rackspace engineering, support and product management, plus external contributions from customers.</p>
<p>Contributors don’t need any special licensing or expensive training. Our platform relies on open source tools and simple workflows.</p>
<p>Under the new documentation model, in addition to the successes I listed above, we standardized writing guidelines and publishing requirements across the support and developer documentation, and simplified and automated writing and publishing processes so writers have more time for higher value activities like content curation, content strategy, quality checking and collaborating more effectively in product planning and development cycles.</p>
<p>Overall, the system enables contributors to produce technical and support documentation fast, collaboratively and with plenty of feedback along the way. Developers can write and review content within the context of their development environment, while writers can collaborate on a multi-functional platform that minimizes manual review and publishing processes.</p>
<h2 id="how-did-we-get-here">How did we get here?</h2>
<p>We developed the new documentation system in phases.</p>
<p>First, a collaborative team of managers, engineers, writers, editors, designers and product managers developed the documentation platform and user interface design. Writing teams developed content migration plans in parallel and began migration when the platform stabilized. After that, the writing team worked on enabling contributions.</p>
<p>We developed contributor guidelines, adapted existing Rackspace style and quality guidelines and developed training. The next step was to develop content templates and outreach programs to raise awareness about the new platform.</p>
<p>Getting the work done and gaining adoption required cultural changes that were often more challenging than the mechanics of adopting the new model.</p>
<p>Writers, support representatives and customers unfamiliar with code tools and code workflows had to learn new skills.
Product and support teams accustomed to delegating documentation work to writers had to become more engaged by writing drafts, reviewing content and updating existing content.
Writing teams had to leave behind more sophisticated authoring tools for lighter weight tools with similar features. This meant losing useful functionality like rich semantic tagging and content reuse, and then having to customize the new tools to implement some of those lost features.
Writing teams had to adapt to authoring collaboratively, which requires more coordination, planning and negotiation.
Writing teams took on more responsibility to curate content, define content strategy, mentor contributors, automate quality checking, analyze usage statistics, and report metrics that demonstrate documentation value.
Development and design teams had to mentor contributors on unfamiliar development tools and workflows.
Detailed information about documentation must now be accounted for in requirement definition, release planning, project management tracking and communication workflows, rather than having the writing team manage that work independently.
Like most change initiatives, our documentation transformation is ongoing. We continue to work on training and outreach efforts to increase contribution. We are refining templates and guidelines to simplify contribution. Everyone is learning new skills.</p>
<p>At the organizational level, our leadership team is strengthening partnerships with product management, development, quality, and design teams to develop tighter integration between documentation activities and product planning and development.</p>
<h2 id="overcoming-challenges">Overcoming challenges</h2>
<p>Cultural changes like the Rackspace documentation project require tremendous organizational support. Many people at Rackspace were involved in this project, including the leadership team, writers, editors, developers, designers, support representatives and others. In the beginning, we faced several challenges:</p>
<p>skepticism about leaving our existing DocBook XML-based tool chain behind,
establishing trust to build a collaborative team to develop the new platform,
working across Rackspace writing teams in San Antonio, Austin and Australia had to find the most efficient method to migrate Rackspace Private Cloud documentation, a few thousand support articles and 25 API guides to plain text formats and learn how to architect content using Jekyll and Sphinx.
As with many large projects, people disagreed and actively disliked some project requirements and task assignments.</p>
<p>While these challenges could have easily derailed our project, a major reason we succeeded is the support we got from our leaders, including Jesse Noller, director of engineering; Ian White, our senior manager at project kickoff, and our current senior manager, Laura Clymer.</p>
<p>We also leveraged Rackspace’s close relationship with the OpenStack community. <a href="https://justwriteclick.com/">Anne Gentle</a> provided expert guidance that continues to inspire our effort to develop a strong, collaborative documentation culture. Another key support was the <a href="https://www.writethedocs.org/">Write the Docs community</a>.</p>
<p>Early on, Rackspace writers attended a Write the Docs conference in Portland. We learned valuable lessons and were motivated by the success of similar projects at other companies. WTD also provided useful information about establishing collaborative relationships across teams and developing the multidisciplinary skills required for collaborative work. The WTD community continues to be a source of guidance and moral support as we navigate continuing challenges.</p>
<h2 id="want-to-learn-more">Want to learn more?</h2>
<p>Are you or your team interested in adopting a docs like code model or improving your documentation development process in general?</p>
<p>The <a href="https://www.writethedocs.org/">WTD website</a> is a great place to begin, with links to conference presentations, a documentation guide and information about conferences and meet ups.</p>
<p>Considering the docs as code model from different perspectives provides valuable insights about the mechanics of the model as well as cultural and process considerations. Evan Goer provides a developer perspective in <a href="https://www.slideshare.net/evangoer/yuiconf-2013documentationiscode">Thinking of Documentation as Code</a>.</p>
<p>For a perspective that consider both the writer and developer perspective, see <a href="https://www.slideshare.net/MargaretEker/docs-ascodemissingmanual-66429726">Docs as Code: The Missing Manual</a>, a presentation that I co-presented at the Write the Docs 2016 European conference. Our talk focused on optimizing the docs as code model by mapping writing and code workflows to identify gaps and opportunities for additional collaboration and automation, particularly test automation.</p>
<p>At the same conference, <a href="https://www.slideshare.net/RachelWhitton3/delivering-highvelocity-docs-that-keep-pace-with-rapid-release-cycles">Rachel Whitton’s talk Delivering High-Velocity Docs that Keep Pace with Rapid Release Cycles</a> captured the details of implementing a docs as code model from the writing and operations perspective.</p>
<p>Finally, another great resource is Anne Gentle’s <a href="https://docslikecode.com/">Docs like Code project</a> that aims to share information and capture best practices for creating documentation collaboratively using code systems.</p>
<p>Are you treating docs like code, or thinking about transforming your documentation processes? We’d love to hear your thoughts and experiences. If you have questions or want to know more about contributing to Rackspace documentation, see our <a href="https://docs.rackspace.com/docs/style-guide/quickstart">Quickstart</a> or e-mail us at devdoc@rackspace.com.</p>
<p>Originally published November 11, 2016, on the <a href="https://blog.rackspace.com/transforming-developer-and-support-documentation-with-docs-like-code">Rackspace Blog</a>.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/rackspace-case-study/">Transforming Developer and Support Documentation with Docs Like Code</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on November 12, 2017.</p>
https://www.docslikecode.com/articles/cisco-devnet-pubhub2017-09-19T00:00:00+00:002017-09-19T00:00:00+00:00Anne Gentlehttps://www.docslikecode.com
<p>Here at Cisco, we have a developer program called DevNet that focuses on making Cisco APIs easier to use as well as work with developers and Cisco partners in many technology areas including IoT, Collaboration, and Software Defined Networking. The Cisco DevNet team loves working with developers, network administrators, and collaborators of all kinds. Mandy Whaley is the Director of Developer Experience for DevNet. I wanted to share details about Cisco’s docs-like-code solution, PubHub, to publish both internally and externally here at Cisco. So, I used her presentation and dug into the technology as well. Here’s the story of how PubHub was developed for publishing content for DevNet.</p>
<blockquote>
<p>APIs need great docs. Many organizations end up with a jungle of wiki pages,
Swagger docs and API consoles, and maybe just a few secret documents trapped
in chat room somewhere… Keeping docs updated and in sync with code can be a > challenge.</p>
<p>We’ve been working on a project at Cisco DevNet to help solve this problem
for engineering teams across Cisco.</p>
<p>The goal is to create a forward looking developer and API doc publishing
pipeline that:</p>
<ol>
<li>
<p>Has a developer friendly editing flow.</p>
</li>
<li>
<p>Accepts many API spec formats (Swagger/OpenAPI, RAML, etc).</p>
</li>
<li>
<p>Supports long form documentation in markdown.</p>
</li>
<li>
<p>Is CI/CD pipeline friendly so that code and docs stay in sync.</p>
</li>
<li>
<p>Flexible enough to be used by a wide scope of teams and technologies.</p>
</li>
</ol>
</blockquote>
<p>What did the DevNet team come up with? Let’s take a look.</p>
<h2 id="what-site-or-sites-do-you-create-from-a-set-of-git-based-repositories">What site or sites do you create from a set of Git-based repositories?</h2>
<p>The site is <a href="https://developer.cisco.com">developer.cisco.com</a>, and content comes from multiple repository sources, with multiple source types including markdown, RAML, and OpenAPI built with YAML or JSON.</p>
<p>There’s also <a href="https://learninglabs.cisco.com">learninglabs.cisco.com</a>, which is also built from repositories containing markdown for content, and JSON files for navigation elements.</p>
<p>Plus, if a team wants to host content on their own site, the PubHub system provides links to content stored in S3 or any object storage system that can be embedded on a site. The technology that enables consistent display, styling, and seamless interaction across multiple sites and repos for all these rendered HTML snippets is a JavaScript SDK, the PubHub front-end SDK.</p>
<h2 id="what-are-the-repositories-that-build-the-deliverables">What are the repositories that build the deliverables?</h2>
<p>The repositories for <a href="https://developer.cisco.com">developer.cisco.com</a> content are all private and hosted on an internal Enterprise GitHub installation, moved over from an internal GitLab installation originally. There are over 450 content repos stored privately and internally, meaning that you must work at Cisco and be invited to collaborate on a particular repo.</p>
<p>Some repositories are public, such as those for the <a href="https://learninglabs.cisco.com">Learning Labs</a>, so they can be browsed publically and patched by anyone on GitHub. There are nearly 200 repos for the DevNet organization itself, but those are not necessarily building learning labs, and the Learning Labs system can accept repos from any organization. There are over 300 Learning Labs available today including 25 written in Japanese.</p>
<h2 id="what-factors-led-your-team-to-choose-a-development-approach-for-docs-why-and-when-was-it-chosen">What factors led your team to choose a development approach for docs? Why and when was it chosen?</h2>
<p>Around 2014, some members of the DevNet team, including Mandy Whaley and API evangelist Ashley Roach, saw a need to work across all of Cisco on API and developer needs. Mandy outlines the needs the development approach met quite well in her All Day DevOps talk: developer workflows for writing and editing, friendly to continuous integration and continuous deployment systems, and flexible enough to spread across all of Cisco as a centralized supporting system for API documentation.</p>
<h2 id="what-type-of-audience-are-you-writing-for">What type of audience are you writing for?</h2>
<p>These sites are for all of Cisco’s products, which vary from IoT (Internet of Things) to collaboration such as WebEx video conference, sophisticated phone systems with Voice Over IP (VOIP), Spark for enterprise chat, to cloud services such as Meraki, and of course our business base, networking products. The audience includes network administrators and developers who automate or manage network configuration and setup. For example, you may have seen Meraki in the small business and organizations you frequent, such as coffee shops or schools, managing the wifi for both customers and staff needs. The audience and their use cases vary and our APIs cover many use cases.</p>
<h2 id="how-active-is-your-review-queue">How active is your review queue?</h2>
<p>Because the system is meant for individual teams to review their own content, the centralized team does not have to review each content change. That said, the DevNet team has tech writers help with content updates, and provides a service for on-boarding new teams who want to use PubHub.</p>
<h2 id="do-you-have-automation-if-so-what-type-or-tooling-and-where-is-the-automation-in-the-workflow">Do you have automation? If so, what type or tooling, and where is the automation in the workflow?</h2>
<p>Yes, absolutely as that’s one of the drivers for the system, is to enable automation and integration into existing CI/CD workflows to keep in sync with code changes. The PubHub system uses Apache Kafka to manage notifications on updates for each repo and then publish them as static files. The automation for publishing is triggered when the team makes a “release” of the repository, indicating that the content is ready for public consumption.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/cisco-devnet-pubhub/">DevOps-friendly Docs Publishing for APIs</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on September 19, 2017.</p>
https://www.docslikecode.com/articles/when-to-wiki2017-08-19T00:00:00+00:002017-08-19T00:00:00+00:00Anne Gentlehttps://www.docslikecode.com
<p>While I was writing <em>Docs Like Code</em>, I went back and forth in my mind, arguing with myself on whether the timing was quite right. I didn’t know for certain if we had reached a tipping point as an industry, or if I was simply seeing a trend relevant only to the open-source, developer-centric world I was embedded in.</p>
<p>And then, I heard from Gene in an email.</p>
<blockquote>
<p>“Whenever I start considering retirement, again, I read one of your articles
and get inspired to keep going. Thank you for your interesting ideas and
willingness to share them.”</p>
</blockquote>
<p>And he kept me going and asked more questions as I went, and I felt energized once again to answer his question about wikis and writing closer to the code.</p>
<p>Gene goes on to share his background, which resonates with both software developers and technical writers who were once some other profession.</p>
<blockquote>
<p>“The Docs Like Code theme resonates with me as a former software developer
and having always been embedded with developers as a tech writer. I think
it’s easier for a developer-writer to buy into the concept than the
traditional tech writer can because the tools and methodology are already
familiar. Myself, I mostly converted because the critical mass behind
Markdown became too great to continue battling against it. My ideas of a
better way gave way to being open to using GitHub and
Markdown/reStructuredText, and looking for opportunities to make that
workflow better.”</p>
</blockquote>
<p>Gene positively nails the place many of us find ourselves today. Converted or converting, migrating from one familiar toolset to another, a less familiar one, and taking the best from one workflow to another workflow to streamline the tasks at hand.</p>
<p>We are living through change management in our content management.</p>
<p>He goes on to ask, with double-spaces after periods, which I find endearing,</p>
<blockquote>
<p>“I still have companies asking about using a wiki for documentation when
considering jettisoning their legacy documentation tools, which aren’t
working. I’m able to dissuade them by saying the proliferation of content
soon becomes unmanageable, and they accept that because they assume I know
what I’m talking about and they don’t when it comes to documentation. Many
of the arguments for using a wiki are the same you give in the Docs Like Code
articles; primarily, collaboration and ease of use.”</p>
</blockquote>
<blockquote>
<p>“What are your thoughts on the differences between using a wiki and using
Git/Markdown, that I might be able to give them more substantive arguments?”</p>
</blockquote>
<p>This is a good question. I love the phrasing of this question because it does not pre-suppose a value judgment on either method.</p>
<p>If I were in his shoes, I’d be curious and ask questions about the reasons for jettisoning – is it because of licensing, authoring, or deliverables they can get from legacy? Or maybe there is a combination of reasons I can’t come up with? That’s interesting, and of course, informs your requirements list and considerations.</p>
<h2 id="consider-the-workflow---sit-in-another-environment">Consider the workflow - sit in another environment</h2>
<p>For me, when moving towards a docs-as-code workflow, my eyes were opened when a developer told me he’d never want to leave his Terminal window to write docs. Think about the context switch from coding to opening a wiki page. Many developers do not see a need to open a browser window simply to log in and edit a page that they have to take time to find in the first place. You can avoid that context switching by placing the docs right in the code or in the same repository as the code. This context switch was a powerful push for me, even when pushing away from my familiar XML territory.</p>
<h2 id="authentication-and-privacy-needs">Authentication and privacy needs</h2>
<p>Sometimes wikis are seen as internal-only documentation sites, which is a good use case because the wiki can be accessed only behind a firewall, for example. GitHub Pages from Github.com are publicly available when published, even when publishing from a private repository. (Updated July 2022: refer to <a href="https://docs.github.com/en/enterprise-cloud@latest/pages/getting-started-with-github-pages/changing-the-visibility-of-your-github-pages-site">Changing the visibility of your GitHub Pages site</a> for information about managing access control for your project site by publishing the site publicly or privately on Enterprise Cloud GitHub.)</p>
<p>You can implement an authentication workflow on a site uploaded to GitHub Pages, but you then need to have the web development resources to maintain the login requirement. You could use GitHub Enterprise Pages with GitHub Enterprise requiring a VPN connection to view pages. Security and openness decisions may preclude one solution or another.</p>
<h2 id="whos-reading-whos-writing">Who’s reading? Who’s writing?</h2>
<p>Does the wiki give you statistics you can use to figure out who knows more about a certain topic? GitHub can enable you to see which contributors are working on a particular part of the software project which can help with documentation needs. Wikis can do this too, a reader was quick to point out, but my sense is that those wikis are truly CMSes and not “quick editors.”</p>
<h2 id="automation-the-game-changer-for-docs-as-code-workflows">Automation, the game-changer for docs-as-code workflows</h2>
<p>Automated builds for review purposes are a huge gain with GitHub for documentation. While wikis have a simple save button per page, for some there is way to write scripts to automate translations or glossary re-use. Now, the more advanced and integrated wikis are certainly moving in this direction, and may sway you away from your static site generator towards a content management wiki. Wikis can be very box-like and rigid, while treating docs like code lets you automate more tasks than simply “render and publish HTML.” These statements are not meant to provide final judgement on either platform.</p>
<h2 id="information-architecture-can-you-get-what-you-want-and-release">Information architecture, can you get what you want and release?</h2>
<p>Wikis are quite page-oriented, and in order to do releases, you might need to publish a page twice, using namespaces for example, if information affects two releases. With GitHub, you can backport a change from one release to another using branches and a similar pull request and review workflow.</p>
<h2 id="reviews">Reviews</h2>
<p>Wikis often have add-ons for review workflows, but when the heart of a wiki is quick editing, people will not easily switch to a review workflow within a wiki while in GitHub it’s expected to let others review your changes before merging, or publishing in the case of a document.</p>
<p>Sprawl can be a problem with both solutions, but the organized nature of code near documentation seems to keep the two in lock-step when the docs and code share systems such as version control and review workflows.</p>
<h2 id="design-and-experiences">Design and experiences</h2>
<p>When publishing an entire site using static sites, you get more flexibility in choosing web designs and navigation than many heavily-opinionated wiki frameworks. That said, if your web development resources know a particular wiki framework really well, they may create a nicer end-user experience in a wiki than in a highly-flexible web framework like Sphinx or Jekyll.</p>
<p>Wikis may have a reputation built up over time with a lack of discipline in editing a page instead of starting a new page, and in gaining trusted information that can be found easily.</p>
<h2 id="bringing-it-home">Bringing it home</h2>
<p>Even as I wrote back to Gene to answer his questions, and even as I incorporated the answers into the <em>Docs Like Code</em> book, I continue to be challenged with my answers and to reconsider some of them. Tools come and go, and our ability as professional writers remains and shines: provide the best critical analysis of the content management tools, and then write and manage the heck out of the content and the talent that creates and maintains it.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/when-to-wiki/">What about wikis? Content management and change management</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on August 19, 2017.</p>
https://www.docslikecode.com/articles/free-open-source-api-doc-tools2017-06-05T00:00:00+00:002017-06-05T00:00:00+00:00Diána Lakatoshttps://www.docslikecode.com
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<h1 id="open-source-api-documentation-generators">Open source API documentation generators</h1>
<p>API providers describe their API’s functionalities with <strong>specifications and definitions</strong>, like OpenAPI/Swagger, RAML, API Blueprint, I/O Docs or WSDL. <strong>API documentation solutions</strong> convert these definitions into a structured, easy to use API documentation for developers.</p>
<p><em>API documentation tools are sometimes named after the type of definition they take, e.g. Swagger generates API documentation from Swagger definitions. They also often include the definition in their naming, e.g. RAML 2 HTML.</em></p>
<h2 id="api-documentation-generators-using-the-swaggeropenapi-specification">API documentation generators using the Swagger/OpenAPI specification</h2>
<p>The Swagger specification is a powerful definition format that describes RESTful APIs. It maps all the resources and operations associated with a RESTful interface and makes it easier to develop and consume an API.</p>
<p>Recently the Swagger standard changed its name to Open API, you can find out more about the initiative at the <a href="https://www.openapis.org/">Open API Initiative</a> website. As a leading standard Swagger/OpenAPI has accumulated a large range of API documentation generators that use the specification format.</p>
<h3 id="swagger">Swagger</h3>
<p><a href="https://swagger.io/">Swagger</a> is a complete framework for describing, producing, consuming, and visualizing RESTful web services.</p>
<p>Use the Swagger ecosystem to create your API documentation: document APIs with JSON using the Swagger spec, and use the Web UI to dynamically convert it into API documentation in a web page. Your API documentation will be displayed through the Swagger UI, which provides a well-structured and good-looking interface.</p>
<p><img src="../../images/pronovix/swagger_ui_example.png" alt="Swagger UI example" width="800" /></p>
<p>Example of an API documentation displayed with the Swagger UI</p>
<p>Swagger is free to use, licensed under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache 2.0 License</a>. You can find all Swagger-related public tools under the <a href="https://github.com/swagger-api">swagger-api GitHub account</a>.</p>
<p>Many <a href="https://swagger.io/open-source-integrations/">open source projects</a> and <a href="https://swagger.io/tools/">tools vendors</a> provide Swagger integrations, so make sure to check out the list of available solutions before building new tooling - there is a big chance you will find an existing solution that fits the needs of your project.</p>
<p>As today’s leading API ecosystem, it’s also the best documented and supported. Should you decide to document your APIs with Swagger, you can find plenty of resources, tutorials, examples and help online.</p>
<h3 id="dapperdox">DapperDox</h3>
<p>With <a href="https://dapperdox.io/">DapperDox</a> you can author readable guides and have them form part of a cohesive set of documentation along with the API specifications: You can inject relevant documentation into the rendered specification page.</p>
<p><img src="../../images/pronovix/dapperdox_overview.png" alt="DapperDox Overview" width="800" /></p>
<p>To create your API documentation with DapperDox, point DapperDox at your <strong>OpenAPI/Swagger</strong> specifications, add some documentation in <strong>Markdown</strong> and let DapperDox do the rest.</p>
<h3 id="redoc">ReDoc</h3>
<p><a href="https://github.com/Redocly/redoc">ReDoc</a> uses the OpenAPI specification and generates a responsive site with a three-panel design. It pulls markdown headings from the OpenAPI description field into the side menu, and supports deep linking.</p>
<p>ReDoc aims to make deployment extremely easy, provides a wide support for OpenAPI objects, and offers interactive documentation for nested objects. You can include code samples via a third-party extension.</p>
<p><img src="../../images/pronovix/redoc-demo.png" alt="Redoc Demo" width="800" /></p>
<h2 id="api-documentation-generators-using-the-raml-specification">API documentation generators using the RAML specification</h2>
<p><a href="https://raml.org/">RAML</a> (RESTful API Modeling Language) helps you manage the whole API lifecycle from design to sharing.</p>
<p>RAML is built on broadly-used standards such as YAML and JSON, and is language neutral with tools for: Java, Javascript, .Net, PHP, Python, Ruby, etc.</p>
<p>To create your API documentation with RAML, you can choose open source tools like the <a href="https://github.com/mulesoft/api-console">API Console</a> or <a href="https://github.com/raml2html/raml2html">RAML 2 HTML</a>. Documentation can be generated quickly and on the fly. With parsers available for many languages you can create your own custom docs and interactive scripts like e.Pages and Spotify.</p>
<h3 id="raml-2-html">RAML 2 HTML</h3>
<p><a href="https://github.com/raml2html/raml2html">RAML 2 HTML</a> is a simple RAML to HTML documentation generator with theme support, written for Node.js.</p>
<p><img src="../../images/pronovix/raml2html_demo.png" alt="RAML2HTML demo" width="800" /></p>
<p>Example of an API documentation displayed with RAML 2 HTML’s default theme</p>
<p>RAML 2 HTML ships with a default theme, but you can install more from NPM. For example, to render RAML to Markdown, you can install the raml2html-markdown-theme.</p>
<h3 id="raml-api-console">RAML Api Console</h3>
<p>Using the <a href="https://github.com/mulesoft/api-console">RAML API Console</a> you can create HTML documentation from a RAML specification. It allows browsing of API documentation and in-browser testing of API methods.</p>
<p>There are two ways you can include the console: directly, or within an iframe.</p>
<p><img src="../../images/pronovix/raml_console_demo.png" alt="RAML Console Demo" width="800" /></p>
<p>Example of an API documentation displayed with the RAML API Console</p>
<h2 id="api-documentation-generators-using-the-api-blueprint-specification">API documentation generators using the API Blueprint specification</h2>
<p><a href="https://apiblueprint.org/">API Blueprint</a> is a Markdown-based document format for writing API descriptions and documentation. With API Blueprint you can quickly design and prototype APIs to be created, or document and test already deployed APIs.</p>
<p>Thanks to its broad adoption there is a wide range of tools built for API Blueprint. From various standalone tools such as mock server, documentation and testing tools to full-featured API life-cycle solutions.</p>
<h3 id="snowboard">Snowboard</h3>
<p><a href="https://github.com/bukalapak/snowboard">Snowboard</a> is an API Blueprint parser and renderer. It offers a colourful default theme illustrating API request types and responses, and can also be used with custom templates.</p>
<p><img src="../../images/pronovix/snowboard_example.png" alt="Snowboard example" width="800" /></p>
<p>Example of an API documentation displayed with Snowboard</p>
<h3 id="aglio">Aglio</h3>
<p><a href="https://github.com/danielgtaylor/aglio">Aglio</a> renders HTML from API Blueprint files, with support for custom colors, templates and themes.</p>
<p><img src="../../images/pronovix/aglio_example.png" alt="Aglio example" width="800" /></p>
<p>Example of an API documentation displayed with Aglio (Cyborg two-column theme)</p>
<h2 id="other-free-and-open-source-api-documentation-generators">Other free and open source API documentation generators</h2>
<p>Besides the ones detailed above, there are plenty of different open source API documentation generators for different languages and API specifications. Here’s a brief summary of the ones we’ve explored:</p>
<ul>
<li><a href="https://github.com/mashery/iodocs">I/O Docs</a>: I/O docs is an API definition format for the TIBCO Mashery network that comes with a live interactive documentation system for RESTful web APIs. By defining APIs at the resource, method and parameter levels in a JSON schema, I/O Docs will generate a JavaScript client interface.</li>
<li><a href="https://github.com/slatedocs/slate">Slate</a>: Slate helps you create responsive API documentation with a clean, intuitive design. Although it’s built in Ruby, when you write docs with Slate, you’re just writing Markdown, which makes it simple to edit and understand. By default, your Slate-generated documentation is hosted in a public Github repository, which makes it simple for other developers to make pull requests to your docs if they find typos or other problems. Of course, if you don’t want to use GitHub, you can also host your docs elsewhere.</li>
<li><a href="https://github.com/mpociot/whiteboard">Whiteboard</a>: A NodeJS based project started from Slate.</li>
<li><a href="https://apidocjs.com/">apiDoc</a>: Inline documentation for RESTful web APIs, that creates a documentation from API annotations in your source code.</li>
<li><a href="https://github.com/cuubez/api-visualizer">CUUBEZ API Visualizer</a>: Java based API solution to visualize the documentation of RESTful web APIs. This API visualizing framework supports all JAXRS based java REST frameworks and non-JAXRS java based REST frameworks that are currently available in the industry.</li>
<li><a href="https://apidox.net/">Apidox</a>: XML powered live interactive API documentation and browsing for RESTful APIs.</li>
<li><a href="https://github.com/Wiredcraft/carte">Carte</a>: A simple Jekyll based documentation website for APIs. Designed as a boilerplate to build your own documentation, heavily inspired by Swagger and I/O docs.</li>
<li><a href="https://github.com/tmcw/docbox">Docbox</a>: A responsive website generated from Markdown documentation content. It’s dynamically updated with React.</li>
</ul>
<p>And a free one:</p>
<ul>
<li><a href="https://api-docs.io/">API Docs</a>: Although not open source, API Docs provides a hosted public API documentation service for OAS (Swagger) and RAML specifications for free. Features like custom domains, themes, and analytics, are available for a nominal cost through the <a href="https://stoplight.io/?utm_source=apidocs&utm_medium=cost">StopLight</a> integration.</li>
</ul>
<h1 id="general-purpose-open-source-documentation-tools">General purpose open source documentation tools</h1>
<p>Although very handy, API documentation generators are not the only way to render and display your API docs. Many general purpose documentation tools can also get the job done. You could consider using them if you already have one in place, or if you have more documentation tasks than documenting your API alone.</p>
<p>A couple of documentation tools you can check out:</p>
<!-- No longer available as of May 2019.
- [Dexy](https://www.dexy.it/): Dexy is a multi-purpose project automation tool with lots of features designed to work with documents. It does the repetitive parts for you, and thus makes it easier to create technical documents. Many developers use it to document APIs, because combined with other open source tools, Dexy is able to run your example code, save the results, fetch data from an API, and post your docs to a blog or a wiki.
-->
<ul>
<li><a href="https://jashkenas.github.io/docco/">Docco</a>: Docco is a quick-and-dirty documentation generator. It produces an HTML document that displays your comments intermingled with your code.</li>
<li><a href="https://doxygen.nl/index.html">Doxygen</a>: Doxygen is the de facto standard tool for generating documentation from annotated C++ sources, but it also supports other popular programming languages such as C, Objective-C, C#, PHP, Java, Python, IDL, Fortran, VHDL, Tcl, and to some extent D. To document your API, generate an online HTML documentation browser or an offline reference manual, and configure Doxygen to extract the code structure from your source files.</li>
</ul>
<p>We mentioned these tools to give you an idea of how you can use general documentation tools for API documentation, but there are many more to choose from, if you’d like to follow this approach.</p>
<h1 id="developer-portals">Developer portals</h1>
<p>Good API documentation is necessary, but not sufficient for a great developer experience, so it’s better to think about the whole experience in terms of a developer portal that will fulfill all developer needs. Besides the API documentation, a developer portal can include guides and tutorials, reference pages, FAQs, forums, other support resources, software development kits, etc. For an overview of all the different types of documentation a good developer portal needs, <a href="https://pronovix.com/blog/developer-portals-best-practices-documentation-patterns">check our blog post series on developer portal components</a> or receive it as a white paper in your mailbox by <a href="https://bit.ly/devportals">subscribing to our Developer Portal mailing list</a>.</p>
<p>At Pronovix, we work with <a href="https://www.drupal.org/">Drupal</a>, an open source content management system to build a full-featured developer portal, a toolbox for developer relations with integrated API documentation.</p>
<p>Drupal has a couple of modules that you can use to document your APIs, one of which is the <a href="https://www.drupal.org/project/api">API module</a> originally developed to produce the Drupal developer documentation available at <a href="https://api.drupal.org/api/drupal">api.drupal.org</a>. It implements a subset of the Doxygen documentation generator specification, with some Drupal-specific additions. If you’d like to publish your API documentation and you plan to extend it into a developer portal, you could give Drupal a try, as it’s free, open source, and has extensive documentation both for the core CMS and the API module.</p>
<p>We have done extensive work with Apigee’s developer portal that is built in Drupal 7, and we are building a new developer portal in Drupal 8, Drupal’s latest release. As API documentation is a key requirement, it will include a custom API documentation generator that can import Swagger/OpenAPI files and that splits the documentation for individual endpoints into separate entities so that you can control access granularly and easily extend your documentation (especially important for partner portals and for organisations that have strong security requirements). Our ultimate goal is to share our developer portal package as an open source Drupal distribution.</p>
<h1 id="conclusion">Conclusion</h1>
<p>As you can see, with some research and hopefully with the help of this post, you have a good chance to find an open source API documentation tool that fits the needs of your project.</p>
<p>Although this article features quite a few solutions, there are many others available or in development, and new ones are popping up continuously. Please let us know in the comments if you’ve tried a solution that you’d recommend to others!</p>
<h1 id="reference">Reference</h1>
<table>
<thead>
<tr class="header">
<th></th>
<th>Quick summary</th>
<th>Source (specification)</th>
<th>Live demo</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>Swagger</td>
<td>Whole ecosystem, lots of integrations<br />
Good-looking UI for docs<br />
Widely used, many resources available</td>
<td>Swagger/OpenAPI</td>
<td><a href="https://petstore.swagger.io/">Swagger demo</a></td>
</tr>
<tr class="even">
<td>DapperDox</td>
<td>Inject relevant documentation right into the rendered specification page</td>
<td>OpenAPI, Markdown</td>
<td><a href="https://dapperdox.io/docs/overview">DapperDox demo</a></td>
</tr>
<tr class="odd">
<td>ReDoc</td>
<td>Easy deployment<br />
Wide support for OpenAPI objects<br />
Interactive, responsive documentation</td>
<td>OpenAPI</td>
<td><a href="https://rebilly.github.io/RebillyAPI/">ReDoc demo</a></td>
</tr>
<tr class="even">
<td>RAML 2 HTML</td>
<td>Simple RAML to HTML documentation generator theme support</td>
<td>RAML, NodeJSwith</td>
<td><a href="https://rawgit.com/raml2html/default-theme/master/examples/helloworld.html">RAML 2 HTML demo</a></td>
</tr>
<tr class="odd">
<td>RAML API Console</td>
<td>Browsing of API documentation and in-browser testing of API methods</td>
<td>RAML, NodeJS</td>
<td><a href="https://anypoint.mulesoft.com/apiplatform/popular/#/portals/organizations/52560d3f-c37a-409d-9887-79e0a9a9ecff/apis/5502/versions/5487/pages/30295">RAML API Console demo</a></td>
</tr>
<tr class="even">
<td>Snowboard</td>
<td>API Blueprint renderer</td>
<td>API Blueprint</td>
<td><a href="https://htmlpreview.github.io/?https://github.com/bukalapak/snowboard/blob/v3/examples/winter/Real%20World%20API.html">Snowboard demo</a></td>
</tr>
<tr class="odd">
<td>Aglio</td>
<td>API Blueprint renderer with many custom themes</td>
<td>API Blueprint</td>
<td><a href="https://htmlpreview.github.io/?https://raw.githubusercontent.com/danielgtaylor/aglio/blob/master/examples/cyborg.html">Aglio demo</a></td>
</tr>
<tr class="even">
<td>I/O Docs</td>
<td>Live interactive API documentation system for I/O Docs specification format</td>
<td>I/O Docs (JSON)</td>
<td><a href="https://support.mashery.com/io-docs">I/O Docs demo</a></td>
</tr>
<tr class="odd">
<td><br />
Slate</td>
<td>Clean, intuitive design<br />
Write in Markdown<br />
Collaboration through GitHub</td>
<td><br />
Markdown (Ruby)</td>
<td><br />
<a href="https://slatedocs.github.io/slate">Slate demo</a></td>
</tr>
<tr class="even">
<td>Whiteboard</td>
<td>NodeJS based Slate alternative</td>
<td>NodeJS</td>
<td>Whiteboard demo was from wifidistribution.com/docs, no longer available as of May 2019</td>
</tr>
<tr class="odd">
<td>apiDoc</td>
<td>Inline documentation for RESTful web APIs</td>
<td>NodeJS</td>
<td><a href="https://apidocjs.com/example/">apiDoc demo</a></td>
</tr>
<tr class="even">
<td>CuuBEZ API Visualizer</td>
<td>Visualize the documentation of RESTful web APIs</td>
<td>Java</td>
<td><a href="https://github.com/cuubez/api-visualizer">CuuBEZ API Visualizer repo</a></td>
</tr>
<tr class="odd">
<td>Apidox</td>
<td>XML powered live interactive API documentation and browsing for RESTful APIs</td>
<td>XML, PHP<br />
</td>
<td><a href="https://apidox.net/demo/apidox.php">Apidox demo</a></td>
</tr>
<tr class="even">
<td>Carte</td>
<td>A simple Jekyll based documentation website<br />
for APIs</td>
<td>Jekyll, YAML</td>
<td><a href="https://wiredcraft.github.io/carte/">Carte demo</a></td>
</tr>
<tr class="odd">
<td>Docbox</td>
<td>A responsive website generated from Markdown documentation content</td>
<td>Markdown</td>
<td><a href="https://50-53007065-gh.circle-artifacts.com/0/tmp/circle-artifacts.8SMOD8H/index.html#our-api">Docbox demo</a></td>
</tr>
<tr class="even">
<td>API Docs<br />
</td>
<td>Free, hosted API documentation</td>
<td>OpenAPI, Swagger, RAML</td>
<td><a href="https://giphy.api-docs.io/1.0/welcome">API Docs demo</a></td>
</tr>
</tbody>
</table>
<h3 id="definitions">Definitions</h3>
<p>An <strong>Application Programming Interface (API)</strong> is a set of clearly defined methods of communication between various software components. Organizations share their APIs so that developers can build applications that use the services of their software.</p>
<p><strong>API documentation</strong> describes what services an API offers and how to use those services. Good quality documentation is essential to developer experience, which in turn will impact the adoption and long-term success of an API.</p>
<h3 id="we-wrote-this-post-for">We wrote this post for:</h3>
<ul>
<li><strong>API providers</strong>: To provide an overview of free and open source tools for companies that want to share, update or customize their API docs or developer portal.</li>
<li><strong>Developer portal builders</strong>: To provide an independent review of existing developer portal solutions that developer teams tasked with building developer portals can use as a reference in discussions with their clients, to make it easier to select the one that best fits their needs.</li>
<li><strong>Technical writers</strong>: To create a resource that tech writers can use to select the API documentation infrastructure that fits best with their existing authoring workflows.</li>
</ul>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/free-open-source-api-doc-tools/">Free and Open Source API Documentation Tools - Pronovix, Diána Lakatos</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on June 05, 2017.</p>
https://www.docslikecode.com/articles/api-docs-with-code2017-06-03T00:00:00+00:002017-06-03T00:00:00+00:00Adam Lockehttps://www.docslikecode.com
<h1 id="a-pirates-life-for-me-documenting-apis-with-swagger">A Pirate’s Life for Me: Documenting APIs with Swagger</h1>
<p>Our team started developing a new API (in C#), which I took as an opportunity to implement Swagger (now the OpenAPI Specification), an open-source project used to describe and document RESTful APIs. I wanted to show our developers and support engineers that injecting documentation into the code can reduce response time, mitigate errors, and decrease the point of entry for new hires. To illustrate those gains, I needed to develop a proof of concept.</p>
<h2 id="why-swagger">Why Swagger?</h2>
<p>Swagger is open source and includes a UI to display your API documentation, which can be built from source code or manually in JSON. Swashbuckle, a combination of ApiExplorer and Swagger UI, enables Swagger for .NET environments, which was just what we needed.</p>
<blockquote>
<p><strong>Note:</strong> This article applies to .NET environments. Swashbuckle uses <a href="https://github.com/domaindrivendev/Swashbuckle.AspNetCore">a different package</a> for .NET Core environments.</p>
</blockquote>
<h2 id="prepare-to-swashbuckle">Prepare to Swashbuckle</h2>
<p>Swashbuckle requires a bit of coding to implement, but using <a href="https://fsprojects.github.io/Paket/">Paket</a> helps to manage .NET dependencies. With Paket, I can add the necessary Swashbuckle NuGet packages to my API project and ensure that they are current. If I need to add more packages, I can install and manage those packages through Paket.</p>
<p>After installing Paket, I run the following command to add Swashbuckle as a dependency to my C# project.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>paket add nuget Swashbuckle.Core project <projectName>
</code></pre></div></div>
<p>Now that Swashbuckle is available to my project, I can add Swashbuckle to the <code class="language-plaintext highlighter-rouge">Startup.cs</code> file, which is the application startup file for the API. I add each of the following Swashbuckle libraries so that the solution can access the necessary methods.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">using</span> <span class="nn">Swashbuckle.Application</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">Swashbuckle.Swagger.Annotations</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">Swashbuckle.Swagger</span><span class="p">;</span>
<span class="k">using</span> <span class="nn">Swashbuckle.Swagger.XmlComments</span><span class="p">;</span>
</code></pre></div></div>
<p>Then, I add the following code (see the example that follows), much of which is supplied in a Swashbuckle example file. In the <code class="language-plaintext highlighter-rouge">SwaggerGeneratorOptions</code> class, I specify the options that I want Swashbuckle to enable.</p>
<ul>
<li>
<p><code class="language-plaintext highlighter-rouge">schemaFilters</code> post-modify complex schemas in the generated output. You can modify schemas for a specific member type or across all member types. The <code class="language-plaintext highlighter-rouge">IModelFilter</code> is now the <code class="language-plaintext highlighter-rouge">ISchemaFilter</code>. We created an <code class="language-plaintext highlighter-rouge">IModelFilter</code> to fix some of the generated output.</p>
</li>
<li>
<p><code class="language-plaintext highlighter-rouge">operationFilters</code> specifies options to modify the generated output. Each entry enables a different modification for operation descriptions.</p>
</li>
</ul>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">namespace</span> <span class="nn">LinkInterface</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">Startup</span>
<span class="p">{</span>
<span class="c1">//Enables Swashbuckle and related Swagger options.</span>
<span class="k">private</span> <span class="k">void</span> <span class="nf">generateSwagger</span><span class="p">(</span><span class="n">HttpConfiguration</span> <span class="n">config</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">config</span><span class="p">.</span><span class="nf">EnsureInitialized</span><span class="p">();</span>
<span class="kt">var</span> <span class="n">swaggerProvider</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">SwaggerGenerator</span><span class="p">(</span>
<span class="n">config</span><span class="p">.</span><span class="n">Services</span><span class="p">.</span><span class="nf">GetApiExplorer</span><span class="p">(),</span>
<span class="n">config</span><span class="p">.</span><span class="n">Formatters</span><span class="p">.</span><span class="n">JsonFormatter</span><span class="p">.</span><span class="n">SerializerSettings</span><span class="p">,</span>
<span class="k">new</span> <span class="n">Dictionary</span><span class="p"><</span><span class="kt">string</span><span class="p">,</span> <span class="n">Info</span><span class="p">></span> <span class="p">{</span>
<span class="n">version</span> <span class="p">=</span> <span class="s">"v1"</span><span class="p">,</span> <span class="n">title</span> <span class="p">=</span> <span class="s">"My API"</span><span class="p">,</span> <span class="n">description</span> <span class="p">=</span> <span class="s">"Provides an interface
</span> <span class="n">between</span> <span class="n">our</span> <span class="n">API</span> <span class="n">and</span> <span class="n">third</span><span class="p">-</span><span class="n">party</span> <span class="n">services</span><span class="s">"
</span> <span class="p">}</span>
<span class="k">new</span> <span class="nf">SwaggerGeneratorOptions</span><span class="p">(</span>
<span class="c1">//Apply your Swagger options here.</span>
<span class="n">schemaIdSelector</span><span class="p">:</span> <span class="p">(</span><span class="n">type</span><span class="p">)</span> <span class="p">=></span> <span class="n">type</span><span class="p">.</span><span class="nf">FriendlyId</span><span class="p">(</span><span class="k">true</span><span class="p">),</span>
<span class="c1">//Implements the SwaggerTitleFilter class, which generates title members</span>
<span class="c1">//in the definitions model of the swagger.json file.</span>
<span class="n">modelFilters</span><span class="p">:</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="n">IModelFilter</span><span class="p">>(){</span><span class="k">new</span> <span class="nf">SwaggerTitleFilter</span><span class="p">()},</span>
<span class="n">conflictingActionsResolver</span><span class="p">:</span> <span class="p">(</span><span class="n">apiDescriptions</span><span class="p">)</span> <span class="p">=></span> <span class="n">apiDescriptions</span><span class="p">.</span><span class="nf">GetEnumerator</span><span class="p">().</span><span class="n">Current</span><span class="p">,</span>
<span class="n">schemaFilters</span><span class="p">:</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="n">ISchemaFilter</span><span class="p">>(){</span><span class="k">new</span> <span class="nf">ApplySwaggerSchemaFilterAttributes</span><span class="p">()},</span>
<span class="n">operationFilters</span><span class="p">:</span> <span class="k">new</span> <span class="n">List</span><span class="p"><</span><span class="n">IOperationFilter</span><span class="p">>()</span>
<span class="p">{</span>
<span class="c1">//Enables XML comments and writes them to the MyAPI.XML file. These comments</span>
<span class="c1">//are included in the generated swagger.json file.</span>
<span class="k">new</span> <span class="nf">ApplyXmlActionComments</span><span class="p">(</span><span class="s">"MyAPI.XML"</span><span class="p">),</span>
<span class="c1">//Enables the SwaggerResponse output class, to specify multiple</span>
<span class="c1">//response codes for the API.</span>
<span class="k">new</span> <span class="nf">ApplySwaggerResponseAttributes</span><span class="p">()</span>
<span class="p">}</span>
<span class="p">);</span>
<span class="kt">var</span> <span class="n">swaggerString</span> <span class="p">=</span> <span class="n">JsonConvert</span><span class="p">.</span><span class="nf">SerializeObject</span><span class="p">(</span>
<span class="n">swaggerDoc</span><span class="p">,</span>
<span class="n">Formatting</span><span class="p">.</span><span class="n">Indented</span><span class="p">,</span>
<span class="k">new</span> <span class="n">JsonSerializerSettings</span>
<span class="p">{</span>
<span class="n">NullValueHandling</span> <span class="p">=</span> <span class="n">NullValueHandling</span><span class="p">.</span><span class="n">Ignore</span><span class="p">,</span>
<span class="n">Converters</span> <span class="p">=</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span><span class="k">new</span> <span class="nf">VendorExtensionsConverter</span><span class="p">()}</span>
<span class="p">}</span>
<span class="p">);</span>
<span class="c1">//Writes the swagger.json file to the \output directory so that it can</span>
<span class="c1">//be consumed by statis site generators.</span>
<span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">StreamWriter</span> <span class="n">file</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="nf">StreamWriter</span><span class="p">(</span><span class="s">"swagger.json"</span><span class="p">);</span>
<span class="n">file</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">swaggerString</span><span class="p">);</span>
<span class="n">file</span><span class="p">.</span><span class="nf">Close</span><span class="p">();</span>
<span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>After enabling these options, I <em>could</em> include code that enables the Swagger UI, but that interface looks a bit outdated. Also, I want to incorporate additional documentation written in Markdown, which the Swagger UI does not support. After reading online forums and posting questions to the <a href="https://www.writethedocs.org/slack/">Write The Docs channel on Slack</a>, I discovered DapperDox.</p>
<h2 id="using-dapperdox">Using DapperDox</h2>
<p><a href="https://dapperdox.io/">DapperDox</a> is an open-source documentation framework for OpenAPI specifications. Instead of having Swashbuckle publish our API specification in the Swagger UI, I added the following code to the <code class="language-plaintext highlighter-rouge">Startup.cs</code> file. This code writes the Swagger specification to a <code class="language-plaintext highlighter-rouge">swagger.json</code> file.</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="n">StreamWriter</span> <span class="n">file</span> <span class="p">=</span> <span class="k">new</span> <span class="n">System</span><span class="p">.</span><span class="n">IO</span><span class="p">.</span><span class="nf">StreamWriter</span><span class="p">(</span><span class="s">"swagger.json"</span><span class="p">);</span>
<span class="n">file</span><span class="p">.</span><span class="nf">WriteLine</span><span class="p">(</span><span class="n">swaggerString</span><span class="p">);</span>
<span class="n">file</span><span class="p">.</span><span class="nf">Close</span><span class="p">();</span>
</code></pre></div></div>
<p>DapperDox reads this file and displays it in its own UI. I installed DapperDox and pointed it at my <code class="language-plaintext highlighter-rouge">swagger.json</code> file, and saw nothing but error messages in my command prompt.</p>
<p>Reading through the <a href="https://dapperdox.io/docs/spec-resource-definitions">DapperDox documentation</a>, I discovered that <em>“When specifying a resource schema object…DapperDox requires that the optional schema object title member is present.”</em> This requirement was problematic because Swashbuckle does not include a method for adding members to a schema in the generated <code class="language-plaintext highlighter-rouge">swagger.json</code> file. Additionally, it took some tinkering in the code for me to realize that the missing title member on the <code class="language-plaintext highlighter-rouge">definitions</code> model is what caused DapperDox to break.</p>
<h2 id="fixing-the-output">Fixing the output</h2>
<p>The Swashbuckle documentation offered little help in this regard, so I turned to one of our developers. After reviewing the code together, my developer counterpart created a <code class="language-plaintext highlighter-rouge">SwaggerTitleFilter</code> method that adds a <code class="language-plaintext highlighter-rouge">title</code> member to the <code class="language-plaintext highlighter-rouge">definitions</code> model in the resulting <code class="language-plaintext highlighter-rouge">swagger.json</code> file. The title member displays in the generated documentation as a link to the referenced object, creating a hyperlink between the two objects.</p>
<p>The following code implements an <code class="language-plaintext highlighter-rouge">IModelFilter</code> that causes Swashbuckle to generate a title member for any schema. The <code class="language-plaintext highlighter-rouge">SwaggerTitleFilter</code> was referenced in the previous code sample</p>
<div class="language-csharp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">namespace</span> <span class="nn">MyAPI.Swagger</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">SwaggerTitleFilter</span> <span class="p">:</span> <span class="n">IModelFilter</span>
<span class="p">{</span>
<span class="k">public</span> <span class="k">void</span> <span class="nf">Apply</span><span class="p">(</span><span class="n">Schema</span> <span class="n">schema</span><span class="p">,</span> <span class="n">ModelFilterContext</span> <span class="n">mfc</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">schema</span><span class="p">.</span><span class="n">vendorExtensions</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="s">"title"</span><span class="p">,</span> <span class="n">mfc</span><span class="p">.</span><span class="n">SystemType</span><span class="p">.</span><span class="n">Name</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>I compiled the code and Swashbuckle generated an updated <code class="language-plaintext highlighter-rouge">swagger.json</code> file. With the <code class="language-plaintext highlighter-rouge">title</code> member added to the <code class="language-plaintext highlighter-rouge">swagger.json</code> output, I pointed DapperDox at the directory containing my <code class="language-plaintext highlighter-rouge">swagger.json</code> file.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>.\dapperdox -spec-dir=C:\Bitbucket\APIproject\source
</code></pre></div></div>
<p>I opened a browser and entered <code class="language-plaintext highlighter-rouge">http://localhost:3123</code>, which is where DapperDox runs by default, and it worked! DapperDox displayed my <code class="language-plaintext highlighter-rouge">swagger.json</code> file and created interactive documentation that clearly displays the requests, responses, and query parameters for the API. I demoed the output to a few developers and support engineers, and they were over the moon.</p>
<p><img src="../../images/DapperDox_API_reference.png" alt="DapperDox API reference screenshot" title="DapperDox API reference screenshot" /></p>
<h2 id="next-steps">Next steps</h2>
<p>With this framework in place, we can extend Swashbuckle to future APIs and use DapperDox to host the <code class="language-plaintext highlighter-rouge">swagger.json</code> file for each. The resulting output lives with the code and provides documentation that developers and support engineers can access locally by running a single command.</p>
<p>To add documentation beyond just the generated JSON output, DapperDox works incredibly well. I can author short tutorials that describe how to integrate our API with third-party services, which developers can easily review and modify through pull requests. As the API grows, we can add a README file that describes enhancements, modifications, and new integration points. Non-API documentation will live in an <code class="language-plaintext highlighter-rouge">\assets</code> directory, which DapperDox includes at build time.</p>
<p>Each time that the code builds, the <code class="language-plaintext highlighter-rouge">swagger.json</code> file updates with the most current information. Developers and support engineers just run the <code class="language-plaintext highlighter-rouge">.\dapperdox</code> command and specify the directory where the <code class="language-plaintext highlighter-rouge">swagger.json</code> file lives. As the code changes, so does the documentation, so technical debt approaches zero.</p>
<h2 id="lessons-learned">Lessons learned</h2>
<p>Static site generators are all the rage and for good reason. Providing a lightweight framework that can be deployed quickly is a huge asset when documenting APIs, especially external-facing documentation. Numerous options are available, but DapperDox felt like the right fit for our needs.</p>
<p>The pain of determining why DapperDox was broken and the additional coding required to fix the problem was worth the effort, and we are poised to integrate this process into the next set of APIs that our team develops.</p>
<!-- Begin MailChimp Signup Form -->
<link href="//cdn-images.mailchimp.com/embedcode/slim-10_7.css" rel="stylesheet" type="text/css" />
<style type="text/css">
/* #mc_embed_signup{background:#fff; clear:left; font:14px Helvetica,Arial,sans-serif; }
Add your own MailChimp form style overrides in your site stylesheet or in this style block.
We recommend moving this block and the preceding CSS link to the HEAD of your HTML file. */
</style>
<blockquote>
<div id="mc_embed_signup">
<form action="//justwriteclick.us1.list-manage.com/subscribe/post?u=3828f8d87d82289b96ff8fd19&id=cc1d483d59" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank" novalidate="">
<div id="mc_embed_signup_scroll">
<i class="fa fa-envelope-square"></i>
<label for="mce-EMAIL">Enter your email for free lessons plus a review checklist in a neat PDF file.</label>
<input type="email" value="" name="EMAIL" class="email" id="mce-EMAIL" placeholder="email address" required="" />
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_3828f8d87d82289b96ff8fd19_cc1d483d59" tabindex="-1" value="" /></div>
<div class="clear"><input type="submit" value="Join now" name="subscribe" id="mc-embedded-subscribe" class="btn btn--inverse" /></div>
</div>
</form>
</div>
</blockquote>
<!--End mc_embed_signup-->
<p><a href="https://www.docslikecode.com/articles/api-docs-with-code/">Documenting APIs with Swagger - Lucas Systems, Adam Locke</a> was originally published by at <a href="https://www.docslikecode.com">Let's Treat Docs Like Code</a> on June 03, 2017.</p>