<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ EZINNE ANNE EMILIA - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ EZINNE ANNE EMILIA - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Mon, 18 May 2026 22:34:17 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/ezinnecodes/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Automate API Documentation Updates with GitHub Actions and OpenAPI Specifications ]]>
                </title>
                <description>
                    <![CDATA[ Maintaining up-to-date API documentation is often one of the biggest pain points for developers and teams. Too often, the API spec changes but the docs lag behind, leaving developers with outdated or inconsistent information. This frustrates consumer... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-automate-api-documentation-updates-with-github-actions-and-openapi-specifications/</link>
                <guid isPermaLink="false">68c0398aeff4d53c8494c5ab</guid>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github-actions ]]>
                    </category>
                
                    <category>
                        <![CDATA[ OpenApi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ EZINNE ANNE EMILIA ]]>
                </dc:creator>
                <pubDate>Tue, 09 Sep 2025 14:28:26 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1757428080226/175085d0-cfea-41a0-aa52-a50ad8212980.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Maintaining up-to-date API documentation is often one of the biggest pain points for developers and teams. Too often, the API spec changes but the docs lag behind, leaving developers with outdated or inconsistent information. This frustrates consumers of your API and increases support overhead.</p>
<p>This is where automation comes in. By combining OpenAPI specifications with GitHub Actions, you can ensure your documentation is always in sync with your API changes.</p>
<ul>
<li><p><strong>OpenAPI</strong> acts as the single reference point for your API design, keeping your docs consistent, accurate, and aligned with your API.</p>
</li>
<li><p><strong>GitHub Actions</strong> automates the workflow, validating your spec, building docs, and publishing to GitHub Pages in seconds.</p>
</li>
</ul>
<p>This tutorial walks you through a working example of how to use GitHub Actions to auto-update your docs.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-repository">How to set up your repository</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-openapi-specification">How to Create the OpenAPI Specification</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-the-api-spec-locally">How to Test the API Spec Locally</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-install-tools">Install tools</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-create-a-landing-page">Create a landing page</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-validate-your-spec">Validate Your Spec</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-preview-in-the-browser">Preview in the Browser</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-push-local-changes-to-github">How to Push Local Changes to GitHub</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-your-github-actions-workflow">How to Set Up Your GitHub Actions Workflow</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-github-pages">How to Set Up GitHub Pages</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-what-is-github-pages">What is GitHub Pages?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-setting-up-github-pages">Setting Up GitHub Pages</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-handle-multiple-versions">How to Handle Multiple Versions</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-about-the-versions">About the Versions</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-version-1-v1">Version 1 (v1)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-version-2-v2">Version 2 (v2)</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-version-3-v3">Version 3 (v3)</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-versions-locally">How to Set Up the Versions Locally</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-validate-the-api-specs">How to Validate the API Specs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-update-the-github-actions-workflow">How to Update the GitHub Actions Workflow</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<ul>
<li><p><a target="_blank" href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">Node.js and npm installed.</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/gitting-things-done-book/">A GitHub account with basic Git knowledge.</a></p>
</li>
<li><p><a target="_blank" href="https://code.visualstudio.com/download">Visual Studio Code Editor</a>.</p>
</li>
<li><p><a target="_blank" href="https://idratherbewriting.com/learnapidoc/">Basic knowledge of documentation and OpenAPI</a>.</p>
</li>
</ul>
<h2 id="heading-how-to-set-up-your-repository">How to Set Up Your Repository</h2>
<p>If you don’t already have one, create a GitHub repository. For this tutorial, I’ll use <code>api-docs</code> as the repo name.</p>
<p>Then open VSCode and create a folder with the same name.</p>
<h2 id="heading-how-to-create-the-openapi-specification">How to Create the OpenAPI Specification</h2>
<p>Inside the folder you just created, create a folder called <code>spec</code> and add a file named <code>greetings.yaml</code> with the following content:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">openapi:</span> <span class="hljs-number">3.0</span><span class="hljs-number">.3</span>
<span class="hljs-attr">info:</span>
  <span class="hljs-attr">title:</span> <span class="hljs-string">Greetings</span> <span class="hljs-string">API</span>
  <span class="hljs-attr">version:</span> <span class="hljs-number">1.0</span><span class="hljs-number">.0</span>
  <span class="hljs-attr">description:</span> <span class="hljs-string">This</span> <span class="hljs-string">is</span> <span class="hljs-string">a</span> <span class="hljs-string">greetings</span> <span class="hljs-string">API</span> <span class="hljs-string">demonstrating</span> <span class="hljs-string">a</span> <span class="hljs-string">simple</span> <span class="hljs-string">greeting</span> <span class="hljs-string">endpoint</span> <span class="hljs-string">with</span> <span class="hljs-string">query</span> <span class="hljs-string">parameters</span> <span class="hljs-string">and</span> <span class="hljs-string">multilingual</span> <span class="hljs-string">support.</span>
  <span class="hljs-attr">license:</span>
    <span class="hljs-attr">name:</span> <span class="hljs-string">MIT</span>
    <span class="hljs-attr">url:</span> <span class="hljs-string">https://opensource.org/licenses/MIT</span>
<span class="hljs-attr">servers:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">url:</span> <span class="hljs-string">https://api.yourdomain.com/v1</span>
    <span class="hljs-attr">description:</span> <span class="hljs-string">Production</span> <span class="hljs-string">server(v1)</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">url:</span> <span class="hljs-string">https://staging.yourdomain.com/v1</span>
    <span class="hljs-attr">description:</span> <span class="hljs-string">Staging</span> <span class="hljs-string">server(v1)</span>
<span class="hljs-attr">security:</span>
  <span class="hljs-bullet">-</span> <span class="hljs-attr">api_key:</span> []
<span class="hljs-attr">paths:</span>
  <span class="hljs-string">/hello:</span>
    <span class="hljs-attr">get:</span>
      <span class="hljs-attr">summary:</span> <span class="hljs-string">Returns</span> <span class="hljs-string">a</span> <span class="hljs-string">greeting</span>
      <span class="hljs-attr">operationId:</span> <span class="hljs-string">getGreeting</span>
      <span class="hljs-attr">parameters:</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">name</span>
          <span class="hljs-attr">in:</span> <span class="hljs-string">query</span>
          <span class="hljs-attr">required:</span> <span class="hljs-literal">false</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">Name</span> <span class="hljs-string">of</span> <span class="hljs-string">the</span> <span class="hljs-string">person</span> <span class="hljs-string">to</span> <span class="hljs-string">greet</span>
          <span class="hljs-attr">schema:</span>
            <span class="hljs-attr">type:</span> <span class="hljs-string">string</span>
            <span class="hljs-attr">example:</span> <span class="hljs-string">Ezinne</span>
        <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">lang</span>
          <span class="hljs-attr">in:</span> <span class="hljs-string">query</span>
          <span class="hljs-attr">required:</span> <span class="hljs-literal">false</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">Language</span> <span class="hljs-string">of</span> <span class="hljs-string">the</span> <span class="hljs-string">greeting</span> <span class="hljs-string">(default</span> <span class="hljs-string">is</span> <span class="hljs-string">English)</span>
          <span class="hljs-attr">schema:</span>
            <span class="hljs-attr">type:</span> <span class="hljs-string">string</span>
            <span class="hljs-attr">enum:</span> [<span class="hljs-string">en</span>, <span class="hljs-string">fr</span>, <span class="hljs-string">es</span>, <span class="hljs-string">ig</span>]
            <span class="hljs-attr">example:</span> <span class="hljs-string">en</span>
      <span class="hljs-attr">responses:</span>
        <span class="hljs-attr">'200':</span>
          <span class="hljs-attr">description:</span> <span class="hljs-string">Successful</span> <span class="hljs-string">response</span>
          <span class="hljs-attr">content:</span>
            <span class="hljs-attr">application/json:</span>
              <span class="hljs-attr">schema:</span>
                <span class="hljs-attr">type:</span> <span class="hljs-string">object</span>
                <span class="hljs-attr">properties:</span>
                  <span class="hljs-attr">message:</span>
                    <span class="hljs-attr">type:</span> <span class="hljs-string">string</span>
              <span class="hljs-attr">examples:</span>
                <span class="hljs-attr">english:</span>
                  <span class="hljs-attr">value:</span> { <span class="hljs-attr">message:</span> <span class="hljs-string">"Hello, Ezinne!"</span> }
                <span class="hljs-attr">french:</span>
                  <span class="hljs-attr">value:</span> { <span class="hljs-attr">message:</span> <span class="hljs-string">"Bonjour, Ezinne!"</span> }
                <span class="hljs-attr">spanish:</span>
                  <span class="hljs-attr">value:</span> { <span class="hljs-attr">message:</span> <span class="hljs-string">"¡Hola, Ezinne!"</span> }
                <span class="hljs-attr">igbo:</span>
                  <span class="hljs-attr">value:</span> { <span class="hljs-attr">message:</span> <span class="hljs-string">"Ndeewo, Ezinne!"</span> }
<span class="hljs-attr">components:</span>
  <span class="hljs-attr">securitySchemes:</span>
    <span class="hljs-attr">api_key:</span>
      <span class="hljs-attr">type:</span> <span class="hljs-string">apiKey</span>
      <span class="hljs-attr">name:</span> <span class="hljs-string">Authorization</span>
      <span class="hljs-attr">in:</span> <span class="hljs-string">header</span>
</code></pre>
<p>This is a simple spec with multilingual greetings. As your API grows (say more languages or versions), keeping docs in sync manually might get tedious. That’s why automation helps.</p>
<h2 id="heading-how-to-test-the-api-spec-locally">How to Test the API Spec Locally</h2>
<h3 id="heading-install-tools">Install tools:</h3>
<p>Before setting GitHub Actions, you can test the API Spec locally on your machine by setting up <a target="_blank" href="https://github.com/Redocly">Redocly</a> (used to be called Redoc) and testing it in an HTML environment.</p>
<p>Redocly is a lightweight, customizable tool to render OpenAPI specs as an interactive HTML documentation. It’s ideal for static site deployment which makes it ideal for this scenario.</p>
<ul>
<li><p>Install Redoc globally with <code>npm install -g @redocly/cli</code></p>
</li>
<li><p>Install http-server globally with <code>npm install -g http-server</code></p>
</li>
</ul>
<p>The http-server is a local server you can use to test the doc on your machine before you push to GitHub and deploy to GitHub Pages.</p>
<h3 id="heading-create-a-landing-page">Create a landing page:</h3>
<p>In your project, make a <code>docs</code> folder and add <code>index.html</code>:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>API Documentation<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>/&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">redoc</span> <span class="hljs-attr">spec-url</span>=<span class="hljs-string">"../spec/greetings.yaml"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">redoc</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-validate-your-spec">Validate Your Spec:</h3>
<p><code>redocly lint spec/greetings.yaml</code></p>
<p>You should see this if there are no errors or warnings:</p>
<pre><code class="lang-powershell">Woohoo! Your API description is valid. 🎉
</code></pre>
<p><strong>Note:</strong> Validating your API Spec before testing is important as it’ll flag any possible errors. This is because Redocly will fail to run the preview if there are any errors in your spec. </p>
<h3 id="heading-preview-in-the-browser">Preview in the browser:</h3>
<p>Run <code>http-server</code>, and you should see this in the terminal:</p>
<pre><code class="lang-powershell">Starting up http<span class="hljs-literal">-server</span>, serving ./
Available on:
  http://<span class="hljs-number">127.0</span>.<span class="hljs-number">0.1</span>:<span class="hljs-number">8080</span>
  http://<span class="hljs-number">192.168</span>.x.x:<span class="hljs-number">8080</span>
Hit CTRL<span class="hljs-literal">-C</span> to stop the server
</code></pre>
<p>Open <a target="_blank" href="http://localhost:8080/docs/index.html"><code>http://127.0.0.1:8080/</code></a> and navigate to <code>/docs</code> to see your docs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756983802999/944b8603-7b2e-477a-8156-fdaa60f7e0af.png" alt="A preview of the API Specification in a Html page" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-how-to-push-local-changes-to-github">How to Push Local Changes to GitHub</h2>
<p>After making local changes, you need to set up the API documentation so it can update automatically whenever you make changes.</p>
<p>Run these commands if you are pushing to the repository for the first time:</p>
<pre><code class="lang-powershell">git init
git add .
git commit <span class="hljs-literal">-m</span> <span class="hljs-string">"first commit"</span>
git branch <span class="hljs-literal">-M</span> main
git remote add origin &lt;your<span class="hljs-literal">-repo</span><span class="hljs-literal">-url</span>&gt;
git push <span class="hljs-literal">-u</span> origin main
</code></pre>
<h2 id="heading-how-to-set-up-your-github-actions-workflow">How to Set Up Your GitHub Actions Workflow</h2>
<p>You can set up your GitHub workflow by creating a few folders.</p>
<p>First, create <code>.github/workflows/</code> in the <code>api-docs</code> folder. Then, inside the <code>workflows</code> folder, create a <code>docs.yml</code>. This is the workflow file that will serve as a trigger to run validation, generate the HTML with Redocly, and deploy to GitHub Pages at the same time.</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">API</span> <span class="hljs-string">Documentation</span> <span class="hljs-string">and</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">to</span> <span class="hljs-string">GitHub</span> <span class="hljs-string">Pages</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
    <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'spec/greetings.yaml'</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build-spec:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">write</span> <span class="hljs-comment"># needed for gh-pages deployment</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-comment"># 1. Checkout repository</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">code</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-comment"># 2. Set up Node.js</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Set</span> <span class="hljs-string">up</span> <span class="hljs-string">Node.js</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-node@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">node-version:</span> <span class="hljs-string">'20'</span>

      <span class="hljs-comment"># 3. Install Redocly CLI</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Install</span> <span class="hljs-string">Redocly</span> <span class="hljs-string">CLI</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">npm</span> <span class="hljs-string">install</span> <span class="hljs-string">-g</span> <span class="hljs-string">@redocly/cli</span>

      <span class="hljs-comment"># 4. Validate OpenAPI spec</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Validate</span> <span class="hljs-string">OpenAPI</span> <span class="hljs-string">Spec</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">redocly</span> <span class="hljs-string">lint</span> <span class="hljs-string">spec/greetings.yaml</span>

      <span class="hljs-comment"># 5. Build output directory</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Create</span> <span class="hljs-string">build</span> <span class="hljs-string">directory</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public</span>

      <span class="hljs-comment"># 6. Copy spec</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">spec</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public/spec</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">cp</span> <span class="hljs-string">spec/greetings.yaml</span> <span class="hljs-string">public/spec/</span>

      <span class="hljs-comment"># 7. Copy landing page</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">landing</span> <span class="hljs-string">page</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">cp</span> <span class="hljs-string">docs/index.html</span> <span class="hljs-string">public/index.html</span>

      <span class="hljs-comment"># 8. Deploy to GitHub Pages</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">to</span> <span class="hljs-string">GitHub</span> <span class="hljs-string">Pages</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">peaceiris/actions-gh-pages@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">github_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">publish_dir:</span> <span class="hljs-string">./public</span>
</code></pre>
<p>Here’s what’s going on in this code:</p>
<ul>
<li><p>Runs when changes are pushed to <code>main</code> that affect <code>spec/greetings.yaml</code>.</p>
</li>
<li><p>Checks out the repo code.</p>
</li>
<li><p>Sets up Node.js and installs Redocly.</p>
</li>
<li><p>Validates your OpenAPI spec (so broken specs won’t deploy).</p>
</li>
<li><p>Copies the spec and index page into a <code>public/</code> folder.</p>
</li>
<li><p>Deploys <code>public/</code> to the <code>gh-pages</code> branch with GitHub Pages.</p>
</li>
</ul>
<p>Since we’re done with local testing, update the file path in the <code>index.html</code>:</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>API Documentation<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>/&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">redoc</span> <span class="hljs-attr">spec-url</span>=<span class="hljs-string">"./spec/greetings.yaml"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">redoc</span>&gt;</span> <span class="hljs-comment">&lt;!--update the filepath to match your gh config--&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This is so the <code>public</code> directory in the workflow will be able to access it correctly.</p>
<p>This workflow will only run when it detects changes in the API Spec (<code>greetings.yml</code>). To see the workflow in action, make a minor edit in the <code>greetings.yaml</code>.</p>
<p>Push the changes to your GitHub repository:</p>
<pre><code class="lang-powershell">git add .
git commit <span class="hljs-literal">-m</span> <span class="hljs-string">'add changes'</span>
git push
</code></pre>
<h2 id="heading-how-to-set-up-github-pages">How to Set Up GitHub Pages</h2>
<h3 id="heading-what-is-github-pages">What is GitHub Pages?</h3>
<p><a target="_blank" href="https://docs.github.com/en/pages/getting-started-with-github-pages/what-is-github-pages">GitHub Pages</a> is a hosting platform owned by GitHub where you can host websites directly from your GitHub account. This means you can publish static sites on the internet using a GitHub domain and anyone with the website link can access it.</p>
<p>There are other hosting platforms you can use to deploy static websites such as <a target="_blank" href="https://www.netlify.com/">Netlify</a> and <a target="_blank" href="https://vercel.com/">Vercel</a>. But using GitHub Pages for this documentation is easier to set up as it’s on the same platform.</p>
<h3 id="heading-setting-up-github-pages">Setting up GitHub Pages</h3>
<p>Set up GitHub Pages by clicking on the Settings tab in your repository.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756985360548/fa3518a7-0b44-4c7b-ae7f-d0e0b17a84c6.png" alt="A preview of the settings tab in the `api-docs` repository" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Under Source, choose:</p>
<ul>
<li><p>Deploy from branch: <code>gh-pages</code></p>
</li>
<li><p>Folder: <code>/ (root)</code></p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756985446692/a4774bcc-1a42-49f8-a9fd-8ca9339808ef.png" alt="A step-by-step preview of the gh-pages and root setup" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<p>Then save and wait for the workflow to finish.</p>
<p>Your docs will be live at: <code>https://&lt;username&gt;.github.io/api-docs</code>.</p>
<h2 id="heading-how-to-handle-multiple-versions">How to Handle Multiple Versions</h2>
<p>What if you had multiple API versions to update? Let’s assume the simple greetings API in this tutorial had more features added to it across different versions. In this case, you can manage the APIs for the different versions in a single page and also build and deploy it automatically. </p>
<h3 id="heading-about-the-versions">About the Versions</h3>
<h4 id="heading-version-1-v1">Version 1 (v1)</h4>
<p>This is the starting point which is <code>greetings.yaml</code>. The API only has a single <code>/hello</code> endpoint that returns a greeting in four languages (English, French, Spanish, or Igbo).</p>
<h4 id="heading-version-2-v2">Version 2 (v2)</h4>
<p>In version 2, the API adds create and read features. You can:</p>
<ul>
<li><p>Use <code>POST /hello</code> to create and save a greeting.</p>
</li>
<li><p>Retrieve greetings by their unique ID with <code>GET /hello/{id}</code>.</p>
</li>
</ul>
<h4 id="heading-version-3-v3">Version 3 (v3)</h4>
<p>Version 3 builds on top of v2 by adding an update functionality. Along with creating and retrieving greetings, you can now update an existing greeting using <code>PUT /hello/{id}</code>.</p>
<h3 id="heading-how-to-set-up-the-versions-locally">How to Set Up the Versions Locally</h3>
<p>First, create a <code>v1</code> folder and move the <code>greetings.yaml</code> file to it. Since we are going to be using versions, you can delete the existing <code>spec</code> folder.</p>
<p>Then, create a <code>v2</code> folder and create a <code>greetings-v2.yaml</code> file. <a target="_blank" href="https://ezinneanne.github.io/api-doc/v2/greetings-v2.yaml">Get the greetings API for version 2 here</a>.</p>
<p>Next, create a <code>v3</code> folder and add <code>greetings-v3.yaml</code> file. <a target="_blank" href="https://ezinneanne.github.io/api-doc/v3/greetings-v3.yaml">Get the greetings API for version 3 here</a>.</p>
<p>To follow the same pattern with others, rename the version 1 file to <code>greetings-v1.yaml</code>. Then update your <code>index.html</code> to accommodate the other two versions.</p>
<pre><code class="lang-xml"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>API Documentation<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">charset</span>=<span class="hljs-string">"utf-8"</span>/&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1"</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">style</span>&gt;</span><span class="css">
      <span class="hljs-selector-tag">body</span> {
        <span class="hljs-attribute">font-family</span>: Arial, sans-serif;
        <span class="hljs-attribute">margin</span>: <span class="hljs-number">0</span>;
      }
      <span class="hljs-selector-tag">header</span> {
        <span class="hljs-attribute">background</span>: <span class="hljs-number">#2c3e50</span>;
        <span class="hljs-attribute">color</span>: white;
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">1rem</span>;
        <span class="hljs-attribute">display</span>: flex;
        <span class="hljs-attribute">justify-content</span>: space-between;
        <span class="hljs-attribute">align-items</span>: center;
      }
      <span class="hljs-selector-tag">select</span> {
        <span class="hljs-attribute">padding</span>: <span class="hljs-number">0.4rem</span>;
        <span class="hljs-attribute">font-size</span>: <span class="hljs-number">1rem</span>;
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">style</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h2</span>&gt;</span>API Documentation<span class="hljs-tag">&lt;/<span class="hljs-name">h2</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">label</span> <span class="hljs-attr">for</span>=<span class="hljs-string">"version"</span>&gt;</span>Version: <span class="hljs-tag">&lt;/<span class="hljs-name">label</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">select</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"version"</span> <span class="hljs-attr">onchange</span>=<span class="hljs-string">"loadSpec()"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"./v1/greetings-v1.yaml"</span>&gt;</span>v1<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"./v2/greetings-v2.yaml"</span>&gt;</span>v2<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">option</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"./v3/greetings-v3.yaml"</span>&gt;</span>v3<span class="hljs-tag">&lt;/<span class="hljs-name">option</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">select</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- ReDoc container --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"redoc-container"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- ReDoc script --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"https://cdn.redoc.ly/redoc/latest/bundles/redoc.standalone.js"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">loadSpec</span>(<span class="hljs-params"></span>) </span>{
        <span class="hljs-keyword">const</span> version = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"version"</span>).value;
        Redoc.init(version, {}, <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"redoc-container"</span>));
      }
      <span class="hljs-comment">// Load default (v1) on first load</span>
      <span class="hljs-built_in">window</span>.onload = loadSpec;
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<h3 id="heading-how-to-validate-the-api-specs">How to Validate the API Specs</h3>
<p>Earlier in this article, I mentioned testing your specification locally. Now that you have two more versions of the greetings API, run the test to highlight and fix any existing errors.</p>
<ul>
<li><p>For the version V2: <code>redocly lint v2/greetings-v2.yaml</code></p>
</li>
<li><p>For the version V3: <code>redocly lint v3/greetings-v3.yaml</code></p>
</li>
</ul>
<h3 id="heading-how-to-update-the-github-actions-workflow">How to Update the GitHub Actions Workflow</h3>
<p>Now that you have three API Spec versions, you need to update your workflow so it will monitor the three spec files and the HTML document for changes, and then push and deploy them to GitHub Pages as well.</p>
<p>Add this to your <code>.github/workflows/docs.yml</code>:</p>
<pre><code class="lang-yaml"><span class="hljs-comment"># Name of the workflow</span>
<span class="hljs-attr">name:</span> <span class="hljs-string">Build</span> <span class="hljs-string">and</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">API</span> <span class="hljs-string">Documentation</span>

<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span>
    <span class="hljs-attr">branches:</span> [ <span class="hljs-string">main</span> ]
    <span class="hljs-attr">paths:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'docs/index.html'</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'v1/greetings-v1.yaml'</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'v2/greetings-v2.yaml'</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'v3/greetings-v3.yaml'</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">build-and-deploy:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>

    <span class="hljs-attr">permissions:</span>
      <span class="hljs-attr">contents:</span> <span class="hljs-string">write</span>

    <span class="hljs-attr">steps:</span>
      <span class="hljs-comment"># 1. Checkout the repository</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">repository</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v4</span>

      <span class="hljs-comment"># 2. Create build directory</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Create</span> <span class="hljs-string">build</span> <span class="hljs-string">directory</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public</span>

      <span class="hljs-comment"># 3. Copy YAML specs into public folder</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">v1</span> <span class="hljs-string">spec</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public/v1</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">cp</span> <span class="hljs-string">v1/greetings-v1.yaml</span> <span class="hljs-string">public/v1/</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">v2</span> <span class="hljs-string">spec</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public/v2</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">cp</span> <span class="hljs-string">v2/greetings-v2.yaml</span> <span class="hljs-string">public/v2/</span>

      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">v3</span> <span class="hljs-string">spec</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">mkdir</span> <span class="hljs-string">-p</span> <span class="hljs-string">public/v3</span> <span class="hljs-string">&amp;&amp;</span> <span class="hljs-string">cp</span> <span class="hljs-string">v3/greetings-v3.yaml</span> <span class="hljs-string">public/v3/</span>

      <span class="hljs-comment"># 4. Copy landing page into public</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Copy</span> <span class="hljs-string">landing</span> <span class="hljs-string">page</span>
        <span class="hljs-attr">run:</span> <span class="hljs-string">cp</span> <span class="hljs-string">docs/index.html</span> <span class="hljs-string">public/index.html</span>

      <span class="hljs-comment"># 5. Deploy to GitHub Pages</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">to</span> <span class="hljs-string">GitHub</span> <span class="hljs-string">Pages</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">peaceiris/actions-gh-pages@v4</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">github_token:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
          <span class="hljs-attr">publish_dir:</span> <span class="hljs-string">./public</span>
</code></pre>
<p>And finally, push the changes and reload the site. This should showcase the updated documentation.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756986868235/9de187f1-12c4-46ca-a73b-daafa353ed1f.png" alt="A preview of the API documentation in a hosted GitHub Pages environment" class="image--center mx-auto" width="600" height="400" loading="lazy"></p>
<h2 id="heading-summary">Summary</h2>
<p>In this tutorial, you have learned how to auto-update your API docs. We started with a single OpenAPI spec and a basic HTML page rendered by Redocly, and tested it locally. We then set up GitHub Actions to automatically validate the spec, copy the files, and deploy the docs to GitHub Pages. Finally, we extended the setup to handle multiple API versions in one place.</p>
<p>With this workflow, your documentation stays accurate, up-to-date, and hassle-free so every change you make to your API spec goes live when you push the changes.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Set Up Documentation as Code with Docusaurus and GitHub Actions ]]>
                </title>
                <description>
                    <![CDATA[ For technical writers, keeping documentation up to date manually can be really frustrating. Issues like outdated guides, broken links, and missing updates are a pain, and they can make writers less productive. These issues can also make it harder for... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/set-up-docs-as-code-with-docusaurus-and-github-actions/</link>
                <guid isPermaLink="false">67a39f467e716749ae8c7b7e</guid>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                    <category>
                        <![CDATA[ docs-as-code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ docusaurus ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ github-actions ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ EZINNE ANNE EMILIA ]]>
                </dc:creator>
                <pubDate>Wed, 05 Feb 2025 17:26:30 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1738248926082/9a2a6855-00d4-4e25-a8bd-c1d645f21de5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>For technical writers, keeping documentation up to date manually can be really frustrating. Issues like outdated guides, broken links, and missing updates are a pain, and they can make writers less productive. These issues can also make it harder for people to effectively use the docs and get correct information.</p>
<p>Documentation as code, or docs as code, is an approach to managing documentation that treats the docs like a codebase. It lets you version, automatically update, and review your docs just like you would do in a codebase. Docs as code helps you make sure that your docs are up to date and that users can gain access to accurate information.</p>
<p>This tutorial will show you how to:</p>
<ul>
<li><p>Create a documentation website using Docusaurus.</p>
</li>
<li><p>Track changes with Git and GitHub.</p>
</li>
<li><p>Build and deploy it to a hosting platform.</p>
</li>
<li><p>Set up a workflow to perform grammatical reviews using GitHub Actions before you merge your changes.</p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>This tutorial is beginner-friendly, but there are some tools you’ll need to have or know in order to follow along:</p>
<ul>
<li><p><a target="_blank" href="https://code.visualstudio.com/download">VSCode IDE (or other IDE of your choice)</a>.</p>
</li>
<li><p><a target="_blank" href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm">Node.js and npm installed.</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/">A GitHub account.</a></p>
</li>
<li><p><a target="_blank" href="https://www.freecodecamp.org/news/gitting-things-done-book/">A reasonable knowledge of how to use Git and GitHub.</a></p>
</li>
</ul>
<h2 id="heading-why-do-technical-writers-use-docs-as-code">Why Do Technical Writers Use Docs as Code?</h2>
<p>Before we dive in, let’s quickly talk about what "docs as code" is and why it matters. Back in 2015, two technical writers at Google came up with the idea to make it easier for developers to contribute to documentation and to better organize their company documents. There were times when they needed to write about an application they were working on, but things were really disorganized. So they came up with this process. Since then, many companies have adopted the approach.</p>
<p>Docs as code is now a popular approach to managing documentation, and it’s supported by many tools that are designed to treat documentation like code. Tom Johnson explains this concept in more detail in <a target="_blank" href="https://idratherbewriting.com/learnapidoc/pubapis_docs_as_code.html">his article on docs as code</a>.</p>
<p>Traditional documentation relies on Word documents and PDFs, where changes are tracked manually or through document revision history. Writers must update and publish content manually, with no way to automate routine tasks.</p>
<p>On the other hand, docs as code borrows principles and tools from software development to make documentation more structured, versioned, and automated. The documentation is stored in version control (like Git), written in lightweight markup languages, and gets updated alongside the code.</p>
<p>This approach ensures that documentation evolves alongside the software, maintains high quality, and allows for efficient collaboration, just like writing code.</p>
<h3 id="heading-tools-well-use-in-this-tutorial">Tools We’ll Use in This Tutorial</h3>
<p>Let’s review the main tools we’ll be using for this tutorial:</p>
<ol>
<li><p>Docusaurus is a tool created by Facebook for creating documentation websites. It supports markdown and mdx. It also supports versioning and custom themes, making it easy to create user-friendly and professional docs.</p>
</li>
<li><p>Vale is a customizable style and grammar checker for writers. It ensures consistent language, tone, and style across technical documents. There are other good linters you could use for review apart from Vale, but that’s what we’ll be using here.</p>
</li>
<li><p>GitHub Actions: A CI/CD tool for automating workflows directly in GitHub. It helps you test, build, and deploy code with ease.</p>
</li>
</ol>
<h2 id="heading-step-1-install-docusaurus">Step 1: Install Docusaurus</h2>
<p>Open your command line terminal and enter the following:</p>
<pre><code class="lang-javascript">npx create-docusaurus@latest docs-<span class="hljs-keyword">as</span>-code-tutorial classic
</code></pre>
<p><code>docs-as-code-tutorial</code> is the name I am using for the site. You can replace it with any other site name if you wish. Select JavaScript as the language you want to use. This will begin to create a new Docusaurus site. After running the code, you’ll see the <code>docs-as-code-tutorial</code> folder in your VSCode workspace. Navigate to the folder.</p>
<p>Next, start the development server so you can see your docs.</p>
<pre><code class="lang-javascript">cd docs-<span class="hljs-keyword">as</span>-code-tutorial
npm start
</code></pre>
<p>With this, the site will start running at <code>localhost:3000</code>.</p>
<p>When you view the site, you’ll see pre-generated content. So, in the next step, you’ll to create a repository and link the local folder to your remote repository.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737868185569/0cf96b6c-770a-4965-b017-1fe54796c673.png" alt="the docusaurus homepage" class="image--center mx-auto" width="1335" height="698" loading="lazy"></p>
<h2 id="heading-step-2-create-a-repository">Step 2: Create a Repository</h2>
<p>Now, you need to create a repository for the <code>docs-as-code-tutorial</code>. So go to your GitHub account and create a new repository.</p>
<p>After creating the repository, you’ll need to link the repository to the folder in your VSCode workspace.</p>
<p>Open a new terminal and run these commands:</p>
<pre><code class="lang-javascript">git init
git add .
git commit -m <span class="hljs-string">"first commit"</span>
git branch -M main
git remote add origin https:<span class="hljs-comment">//github.com/myname/docs-as-code-tutorial.git</span>
git push -u origin main
</code></pre>
<p>With that, you have linked the repository, and Git will start tracking your changes.</p>
<h2 id="heading-step-3-customize-your-docs-in-the-docusaurusconfig-file">Step 3: Customize your Docs in the <code>docusaurus.config</code> File</h2>
<p>Before you begin customizing, create a branch where you can make your changes as you push it to the main branch.</p>
<pre><code class="lang-powershell">git checkout <span class="hljs-literal">-b</span> <span class="hljs-string">"new_branch"</span>
</code></pre>
<p>The <code>docusaurus.config.js</code> file is where you can make most of the edits to your site. Change the <code>title</code> property to <code>Docs as code</code>.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> config = {
  <span class="hljs-attr">title</span>: <span class="hljs-string">'Docs as code'</span>,
  <span class="hljs-attr">tagline</span>: <span class="hljs-string">'Documentation as code'</span>,
<span class="hljs-comment">//rest of your code</span>
   <span class="hljs-attr">navbar</span>: {
        <span class="hljs-attr">title</span>: <span class="hljs-string">'Docs as code'</span>,
<span class="hljs-comment">//rest of your code</span>
  }
}
</code></pre>
<p>That will show as the new title when you preview the docs. This is simply an illustration to display how Docusaurus works. You can further customize the site to your desired style, but we won’t go into more detail on that here (as the main purpose of this tutorial is to show how to set up your docs as code).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737869529640/c4dab104-9f8b-4dad-a3a5-250d15d4552d.png" alt="c4dab104-9f8b-4dad-a3a5-250d15d4552d" class="image--center mx-auto" width="1337" height="654" loading="lazy"></p>
<p>After making the changes, the site should look a bit different.</p>
<p>You can push the changes now.</p>
<pre><code class="lang-powershell">git commit <span class="hljs-literal">-am</span> <span class="hljs-string">"first commit"</span>
git push -<span class="hljs-literal">-set</span><span class="hljs-literal">-upstream</span> origin new_branch
</code></pre>
<h2 id="heading-step-4-edit-your-docs">Step 4: Edit Your Docs</h2>
<p>For this tutorial, I’ll be making edits in the <code>docs</code> section. Go to <code>intro.md</code> and replace the markdown text with this writeup:</p>
<pre><code class="lang-markdown"><span class="hljs-section"># How to set up docs-as-code</span>

Documentation-as-code is a great means to push changes made in your local machine to your docs live site. To accomplish this, you need an IDE, a static site generator, a Git repository, CI/CD to set up workflows, and a hosting platform. 

<span class="hljs-section">## Why do technical writers do docs-as-code?</span>

Documentation-as-code is a great means to push changes made in your local machine to your docs live site. To accomplish this, you need an IDE, a static site generator, a Git repository, CI/CD to set up workflows, and a hosting platform.
</code></pre>
<p>After making the edits, preview your docs.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737870301247/dba83233-a11c-4ec0-aeaf-b11e525ca090.png" alt="intro.md displaying the writeup " class="image--center mx-auto" width="1335" height="650" loading="lazy"></p>
<h2 id="heading-step-5-add-the-linting-feature">Step 5: Add the Linting Feature</h2>
<p>Add the Vale linter to your docs to review errors. To do that, install the Vale CLI with any of these commands.</p>
<ul>
<li><p>Run <code>choco install vale</code> for Windows</p>
</li>
<li><p><code>brew install vale</code> for MacOs, or</p>
</li>
<li><p><code>snap install vale</code> for Linux</p>
</li>
</ul>
<h3 id="heading-how-to-set-up-vale"><strong>How to set up Vale</strong></h3>
<p>As I mentioned earlier, Vale is a customizable style and grammer checking tool. This means you can set it up to review your docs exactly how you want.</p>
<p>Vale uses the Vale style guide when performing reviews to spot errors and make suggestions. But you can add your company’s style guide or any other style guide to it if you prefer. There are public style guides you can use like the Google style guide, Microsoft style guide, and so on. For this tutorial, we’ll be using the Microsoft style guide.</p>
<p>If you don’t already have it, you’ll need to <a target="_blank" href="https://github.com/errata-ai/Microsoft/releases/download/v0.7.0/Microsoft.zip">get the Microsoft style guide</a>, download it, and unzip it. Create a styles folder and move the Microsoft folder to the styles folder.</p>
<p>This should be your file path:</p>
<pre><code class="lang-javascript">- docs-<span class="hljs-keyword">as</span>-code-tutorial
  <span class="hljs-comment">//other folders</span>
  - styles
    - Microsoft
  <span class="hljs-comment">//other folders</span>
</code></pre>
<p>In your docs, create a <code>.vale.ini</code> file and add it to your root. </p>
<p>Add this code in it:</p>
<pre><code class="lang-plaintext">StylesPath = styles

MinAlertLevel = suggestion

[*.md]

BasedOnStyles = Vale, Microsoft
</code></pre>
<p>Let’s understand what’s going on here:</p>
<ul>
<li><p>The <code>StylesPath</code> is set to the styles folder where you added the Microsoft style guide you downloaded. The MinAlertLevel sets Vale alerts to <code>suggestion</code> – this means that Vale will highlight suggestions, warnings, and errors found in your docs. If the MinAlertLevel is set to errors, then Vale will highlight errors only. If set to warnings, then it’ll highlight warnings and errors (and so on).</p>
</li>
<li><p><code>[*.md]</code> tells Vale to go through <code>.md</code> files only.</p>
</li>
<li><p><code>BasedOnStyles</code> indicates which style guide you are using for the linting. In this case, it’s the Microsoft style guide and Vale style guide. So when the linter is running, it will highlight suggestions, warnings, and errors using the specified style guides.</p>
</li>
</ul>
<p>To test your docs, run <code>vale intro.md</code> (assuming you still have the <code>intro.md</code> file).</p>
<p>This should be the output:</p>
<pre><code class="lang-plaintext">✔ 0 errors, 0 warnings and 0 suggestions in stdin.
</code></pre>
<h2 id="heading-step-6-build-the-site">Step 6: Build the Site</h2>
<p>To do this, run <code>npm run build</code>. After that, you can preview the build with <code>npm run serve</code>.</p>
<h2 id="heading-step-7-deploy-the-site">Step 7: Deploy the Site</h2>
<p>There are different hosting platforms where you can host your live site. This tutorial covers two hosting options: GitHub Pages and Netlify.</p>
<h3 id="heading-deploy-with-github-pages"><strong>Deploy with GitHub Pages</strong></h3>
<p>To deploy to GitHub Pages, you’ll need to set your repository name and GitHub username/organization name in the <code>docusauraus.config.js</code> file.</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Set the production url of your site here</span>

  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://ezinneanne.github.io/'</span>,

  <span class="hljs-comment">// Set the /&lt;baseUrl&gt;/ pathname under which your site is served</span>

  <span class="hljs-comment">// For GitHub pages deployment, it is often '/&lt;projectName&gt;/'</span>

  <span class="hljs-attr">baseUrl</span>: <span class="hljs-string">'/docs-as-code-tutorial/'</span>,

  <span class="hljs-comment">// GitHub pages deployment config.</span>

  <span class="hljs-comment">// If you aren't using GitHub pages, you don't need these.</span>

  <span class="hljs-attr">organizationName</span>: <span class="hljs-string">'ezinneanne'</span>, <span class="hljs-comment">// Usually your GitHub org/user name.</span>

  <span class="hljs-attr">projectName</span>: <span class="hljs-string">'docs-as-code-tutorial'</span>, <span class="hljs-comment">// Usually your repo name.</span>
</code></pre>
<p>You can deploy the site to GitHub Pages in the following ways:</p>
<ul>
<li><p>Using the Powershell terminal with this command:</p>
<p>  <code>cmd /C 'set "GIT_USER=&lt;GITHUB_USERNAME&gt;" &amp;&amp; yarn deploy'</code> </p>
</li>
<li><p>Using the Windows Command line terminal with this command:</p>
<p>  <code>cmd /C "set "GIT_USER=&lt;GITHUB_USERNAME&gt;" &amp;&amp; yarn deploy"</code></p>
</li>
<li><p>Using Bash with this command:<br>  <code>GIT_USER=&lt;GITHUB_USERNAME&gt; yarn deploy</code></p>
</li>
</ul>
<p>Just make sure you replace <code>&lt;GITHUB_USERNAME&gt;</code> with your username on GitHub.</p>
<p>Voilà! The site is deployed at <a target="_blank" href="https://ezinneanne.github.io/docs-as-code-tutorial/">https://ezinneanne.github.io/docs-as-code-tutorial/</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737918709225/3eb12747-4a13-4c17-a7ad-ab6ee84b64ff.png" alt="the docs-as-code homepage deployed on Github Pages" class="image--center mx-auto" width="1336" height="690" loading="lazy"></p>
<h3 id="heading-deploy-with-netlify"><strong>Deploy with Netlify</strong></h3>
<p>To deploy to Netlify, you only need the production URL and base URL:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">// Set the production url of your site here</span>

  <span class="hljs-attr">url</span>: <span class="hljs-string">'https://docs-as-code-tutorial.netlify.app'</span>,

  <span class="hljs-attr">baseUrl</span>: <span class="hljs-string">'/'</span>,
</code></pre>
<ol>
<li><p>Go to your <a target="_blank" href="https://www.netlify.com/">Netlify account</a> and link your repository.</p>
</li>
<li><p>Click on <code>Add new site</code>.</p>
</li>
<li><p>Click on <code>import an existing project</code>.</p>
</li>
<li><p>Connect to your GitHub account and select the <code>docs-as-code-tutorial</code> repository.</p>
</li>
<li><p>Give your site a name, it should be the same as the URL in your <code>docusaurus.config.js</code>.</p>
</li>
<li><p>Add the publish directory which is <code>build</code> and the build command which is <code>npm run build</code>. Then Netlify will deploy to your default branch <code>main</code>, unless you specify otherwise.</p>
</li>
<li><p>Finally, deploy!</p>
</li>
</ol>
<p>You should see the site running at <a target="_blank" href="https://docs-as-code-tutorial.netlify.app/">https://docs-as-code-tutorial.netlify.app/</a>.</p>
<p>For other deployment options, <a target="_blank" href="https://docs-as-code-tutorial.netlify.app/">you can</a> <a target="_blank" href="https://docusaurus.io/docs/deployment">check out the Docusauraus documentation</a>.</p>
<h2 id="heading-step-8-set-up-a-documentation-workflow-using-github-actions">Step 8: Set Up a Documentation Workflow Using GitHub Actions</h2>
<p>Now we’ll set up a workflow for the documentation. In GitHub, when you deploy to GitHub Pages, it sets up a default workflow for you at <code>pages-build-deployments</code>.</p>
<p>Netlify also automates deployments but does not create a workflow file in your repository. Instead, it manages the process through its platform, monitoring your repository for changes and running builds based on your settings. In this tutorial, we will set up a workflow with GitHub Actions that automates Vale running linting checks through the docs.</p>
<p>Create a <code>.github/workflows</code> directory and add a <code>vale-linter.yml</code> file in it. </p>
<p>Add this code in it:</p>
<pre><code class="lang-yaml"><span class="hljs-attr">name:</span> <span class="hljs-string">Vale</span> <span class="hljs-string">Lint</span> <span class="hljs-string">Checker</span>

<span class="hljs-comment"># Trigger the workflow on specific events.</span>
<span class="hljs-attr">on:</span>
  <span class="hljs-attr">push:</span> <span class="hljs-comment"># Run on every push to the main branch.</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">main</span>
  <span class="hljs-attr">pull_request:</span> <span class="hljs-comment"># Run on pull requests targeting any branch.</span>
    <span class="hljs-attr">branches:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">'*'</span>
  <span class="hljs-attr">workflow_dispatch:</span> <span class="hljs-comment"># Allow manual triggering from the Actions tab.</span>

<span class="hljs-attr">jobs:</span>
  <span class="hljs-attr">prose:</span>
    <span class="hljs-attr">runs-on:</span> <span class="hljs-string">ubuntu-latest</span>
    <span class="hljs-attr">steps:</span>
      <span class="hljs-comment"># Step 1: Check out the repository code.</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Checkout</span> <span class="hljs-string">Code</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/checkout@v3</span> 

      <span class="hljs-comment"># Step 2: Set up Node.js</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Setup</span> <span class="hljs-string">Node.js</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">actions/setup-node@v3</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">node-version:</span> <span class="hljs-number">16</span> <span class="hljs-comment"># Use Node.js 16 or higher</span>

      <span class="hljs-comment"># Step 3: Run Vale lint checks.</span>
      <span class="hljs-bullet">-</span> <span class="hljs-attr">name:</span> <span class="hljs-string">Vale</span> <span class="hljs-string">Lint</span>
        <span class="hljs-attr">uses:</span> <span class="hljs-string">errata-ai/vale-action@reviewdog</span>
        <span class="hljs-attr">with:</span>
          <span class="hljs-attr">files:</span> <span class="hljs-string">.</span>
        <span class="hljs-attr">env:</span>
          <span class="hljs-attr">GITHUB_TOKEN:</span> <span class="hljs-string">${{</span> <span class="hljs-string">secrets.GITHUB_TOKEN</span> <span class="hljs-string">}}</span>
</code></pre>
<p>After making these changes, run the following commands:</p>
<pre><code class="lang-powershell">git add .
git commit <span class="hljs-literal">-m</span> “changes”
</code></pre>
<p>Finally push to the repository with <code>git push</code>.</p>
<p>Go to the <code>Actions</code> tab on your repository. You should see the workflow running:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737521586319/3d554246-f8e6-4885-bac5-2cead1b3dd56.png" alt="The github repository page with focus on the Actions tab showing the vale workflow" class="image--center mx-auto" width="1347" height="519" loading="lazy"></p>
<p>Click on the <code>changes</code> button and click on the job <code>prose</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737970927236/632e2753-5d2e-474b-a05e-74a9affa634d.png" alt="A brief preview of the lint output from vale in the prose job run" class="image--center mx-auto" width="1317" height="657" loading="lazy"></p>
<p>Now, you should see all the lines in your <code>.md</code> files highlighted by Vale.</p>
<p>With this, your docs are set up to run like a codebase! You can make changes, and when you push, review, and merge, it will sync automatically.</p>
<p>Keep in mind that this is for Netlify. For GitHub Pages, you’ll need to set up a workflow for automatic deployment.</p>
<h2 id="heading-summary">Summary</h2>
<p>In this tutorial, you have learned how to set up documentation as code using Docusaurus. You also saw how to deploy your documentation to a live site, and automate the linting workflow with Vale and GitHub Actions.</p>
<p><a target="_blank" href="https://docs.github.com/en/actions/use-cases-and-examples/creating-an-example-workflow">There are other workflows</a> you can set up to ease the workload in managing your doc site. Remember, the main point is to organize and structure your docs while automating regular documentation practices using software development tools. This lets you focus on the most important thing which is creating quality content for your readers.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Write Accessible Technical Documentation – Best Practices with Examples ]]>
                </title>
                <description>
                    <![CDATA[ When you're writing technical documentation for a project or a tool you're working on, you'll want it to be accessible. This means that it will cater to and be usable by the diverse global audience on the web. Web accessibility aims to make it possib... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/best-practices-for-writing-accessible-technical-documentation/</link>
                <guid isPermaLink="false">66d84fe57211ea6be29e1b6d</guid>
                
                    <category>
                        <![CDATA[ a11y ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Accessibility ]]>
                    </category>
                
                    <category>
                        <![CDATA[ best practices ]]>
                    </category>
                
                    <category>
                        <![CDATA[ documentation ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ EZINNE ANNE EMILIA ]]>
                </dc:creator>
                <pubDate>Thu, 11 Apr 2024 23:03:04 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/20240401_161256_0000.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>When you're writing technical documentation for a project or a tool you're working on, you'll want it to be accessible. This means that it will cater to and be usable by the diverse global audience on the web.</p>
<p>Web accessibility aims to make it possible for anyone to access web content. There are common accessibility best practices for designers, developers, and writers. This article will cover some best practices for creating technical content.‌</p>
<h2 id="heading-what-is-web-accessibility">What is Web Accessibility?</h2>
<p><a target="_blank" href="https://www.freecodecamp.org/news/web-accessibility-for-devs/">Web accessibility</a> is the practice of making it possible for anyone to consume or create content on the web, regardless of any health, economic, geographic, or language challenges they may have.</p>
<h2 id="heading-why-is-web-accessibility-important">Why is Web Accessibility Important?</h2>
<p>It is important to apply web accessibility best practices in your projects for a number of reasons.</p>
<p>First, it'll help you reach a wider audience. When a person who may have different abilities comes across some data on the web – say on your website – they'll want to learn more or use the data. But if they are not able to access it, you will not be happy or have a good experience.</p>
<p>Imagine how many people are unable to utilize the web because they are not considered when devs and designers are making decisions about how the product, website, or tool will be built.</p>
<p>Another important thing about accessibility is that it improves your brand's quality. Letting people know you are an accessibility-oriented person or company by implementing it in your work shows that you want your information to be available t everyone. It also displays your versatility in your craft and your ability to improve and adapt with changing times and trends.</p>
<p>Also, as an individual, applying accessibility best practices benefits you as well. There are possible employment opportunities for developers and designers with great accessibility skills.</p>
<p>Good accessibility practices mean good SEO practices too, which can result in more visibility for your work.</p>
<p>Finally, accessibility is enforced by law in certain countries around the world, and web accessibility strategies are implemented by certain countries. There could be legal consequences if you overlook accessibility on your websites and apps.</p>
<h2 id="heading-how-to-write-accessible-technical-documentation">How to Write Accessible Technical Documentation</h2>
<p>Software engineers have a key role in making the web accessible. But when it comes to writing documentation, technical writers also have a role to play in improving web accessibility.</p>
<p>Technical writers help write various types of content, like user guides, tutorials, API references, code documentation, and so on.</p>
<p>Now, let's look at some of the best practices for implementing web accessibility in technical writing. These strategies will help improve your documentation and make it more user-friendly and accessible to everyone.</p>
<h3 id="heading-use-clear-headings-and-paragraphs">Use clear headings and paragraphs</h3>
<p>When writing content, you should make sure to use headings – along with the proper heading hierarchy (H1 for the title of the page/article, H2 for major headings, H3 for subheadings, and so on).</p>
<p>Also, make sure to break your content up into paragraphs so it's easier to read and understand.</p>
<p>When you introduce a new topic, use a heading to call that out. When you talk about smaller topics within that section, use subheadings to alert the reader.</p>
<p>Headings are also important to help screen readers understand a page's contents and how to navigate through them. So use headings to help guide readers through the text in a logical manner.</p>
<p>You denote headings in markdown with hashes. Here's an example of headings in hierarchical order.‌</p>
<pre><code class="lang-css"># <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H1</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">page</span> <span class="hljs-selector-tag">title</span>

## <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H2</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">major</span> <span class="hljs-selector-tag">headings</span> 
<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">section</span> <span class="hljs-selector-tag">content</span>. 

### <span class="hljs-selector-tag">Use</span> <span class="hljs-selector-tag">H3</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">subheadings</span> 
<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">heading</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">subheading</span> <span class="hljs-selector-tag">that</span> <span class="hljs-selector-tag">goes</span> <span class="hljs-selector-tag">deeper</span> <span class="hljs-selector-tag">into</span> <span class="hljs-selector-tag">one</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">section</span>'<span class="hljs-selector-tag">s</span> <span class="hljs-selector-tag">points</span>.
</code></pre>
<h3 id="heading-make-your-content-clear-and-concise">Make your content clear and concise</h3>
<p>Overall, try to keep your sentences quite short in your docs. This makes them easier to read and understand (for everyone). You can also use images or videos to provide more details if needed.</p>
<p>Make sure you give the full meanings of any acronyms you are using for the first time. Also, always use simple sentences, and try not to use ambiguous words.</p>
<p>Here's an example of an overly complex, long sentence with difficult vocabulary:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">The</span> <span class="hljs-selector-tag">web3</span> <span class="hljs-selector-tag">running</span> <span class="hljs-selector-tag">on</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">Blockchain</span> <span class="hljs-selector-tag">structure</span> <span class="hljs-selector-tag">which</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">transparent</span>, <span class="hljs-selector-tag">secure</span>, <span class="hljs-selector-tag">immutable</span>, <span class="hljs-selector-tag">decentralized</span> <span class="hljs-selector-tag">would</span> <span class="hljs-selector-tag">require</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">processes</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">artificial</span> <span class="hljs-selector-tag">intelligence</span>, <span class="hljs-selector-tag">where</span> <span class="hljs-selector-tag">it</span> <span class="hljs-selector-tag">would</span> <span class="hljs-selector-tag">read</span> <span class="hljs-selector-tag">data</span>, <span class="hljs-selector-tag">process</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">store</span> <span class="hljs-selector-tag">information</span>.
</code></pre>
<p>This is better:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">Web3</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">built</span> <span class="hljs-selector-tag">on</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">transparent</span>, <span class="hljs-selector-tag">secure</span>, <span class="hljs-selector-tag">unchangable</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">decentralized</span> <span class="hljs-selector-tag">structure</span> <span class="hljs-selector-tag">of</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">blockchain</span>. <span class="hljs-selector-tag">It</span> <span class="hljs-selector-tag">uses</span> <span class="hljs-selector-tag">artificial</span> <span class="hljs-selector-tag">intelligence</span> <span class="hljs-selector-tag">processes</span> <span class="hljs-selector-tag">to</span> <span class="hljs-selector-tag">read</span>, <span class="hljs-selector-tag">process</span>, <span class="hljs-selector-tag">and</span> <span class="hljs-selector-tag">store</span> <span class="hljs-selector-tag">information</span>.
</code></pre>
<p>Your content should contain the main points you're trying to make, removing all forms of ambiguity.‌ ‌</p>
<h3 id="heading-use-informative-link-text">Use informative link text</h3>
<p>All your in-line links should use clear, detailed, and descriptive text. You can describe the link's purpose or the company's name if it is a brand, for example.</p>
<p>Links are important for improving the ranking of a page. And using links like "Click here" or "Read More" is not all that helpful, as they don't tell the reader much about what they'll find at that link.</p>
<p>For instance, if I wanted to link a W3C (World Wide Web Consortium) accessibility tutorial to this article, I could use the following format: Check out <a target="_blank" href="https://www.w3.org/WAI/roles/writers/">these resources for content writers by W3C</a>.</p>
<h3 id="heading-add-alt-text-and-captions-to-media-content">Add alt text and captions to media content</h3>
<h4 id="heading-images">Images</h4>
<p>Adding descriptive text to the alt text attribute allows screen readers to be able to read out the alt text associated with an image. Alt text also helps search engine bots that crawl the page know how to classify that content.</p>
<p>When you're adding alt text, describe the purpose of the image and not what the image is. For instance, let's say you're using an image that shows some shipping containers in a section that is about containerization.‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/containers-1.jpeg" alt="Various containers on a ship in motion to illustrate the packaging structure and process of a digital container." width="600" height="400" loading="lazy"></p>
<p><em>Various containers on a ship in motion to illustrate the packaging structure and process of a digital container.</em></p>
<p>Instead of writing alt text like "various containers on a ship in motion", you could write "various containers on a ship in motion to illustrate the packaging structure and process of a digital container."</p>
<p>While alt text serves as an alternative for the image, captions give more details about the image. You can use HTML to insert image captions. Markdown does not support image captions, but markdown documentation sites usually have a way around it (for example, through plugins – ReadTheDocs, MkDocs – or inserting HTML via a custom component –Docusaurus).</p>
<p>As an example, I'll show you how to add image captions in Docusaurus.</p>
<p><strong>How to add image captions in a Docusaurus .md file:</strong></p>
<ul>
<li><p>Create a folder <code>components</code> in the <code>src</code> folder.</p>
</li>
<li><p>Create a file named <code>figure.jsx</code>.</p>
</li>
<li><p>Add this line of code to it:</p>
</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">React</span> <span class="hljs-selector-tag">from</span> "<span class="hljs-selector-tag">react</span>"; 
<span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">useBaseUrl</span> <span class="hljs-selector-tag">from</span> "<span class="hljs-keyword">@docusaurus</span>/useBaseUrl"; 
<span class="hljs-selector-tag">export</span> <span class="hljs-selector-tag">default</span> <span class="hljs-selector-tag">function</span> <span class="hljs-selector-tag">Figure</span>({ src, caption }) {
  return ( 
  &lt;figure&gt; &lt;img src={useBaseUrl(src)} <span class="hljs-selector-tag">alt</span>={caption} /&gt; 
  &lt;<span class="hljs-selector-tag">figcaption</span>&gt;{`<span class="hljs-attribute">Figure</span>: ${caption}`}&lt;/<span class="hljs-selector-tag">figcaption</span>&gt; &lt;/<span class="hljs-selector-tag">figure</span>&gt; 
  ); 
}
</code></pre>
<ul>
<li>Go to the <code>.md</code> file where you have the image and import the code.</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">Figure</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/figure'; 
<span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">figure1</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-selector-tag">path-to-image</span>';
</code></pre>
<ul>
<li>Add it to the file.</li>
</ul>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">Figure</span> <span class="hljs-selector-tag">caption</span>="<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">a</span> <span class="hljs-selector-tag">caption</span> <span class="hljs-selector-tag">for</span> <span class="hljs-selector-tag">the</span> <span class="hljs-selector-tag">image</span>" <span class="hljs-selector-tag">alt</span>="<span class="hljs-selector-tag">This</span> <span class="hljs-selector-tag">is</span> <span class="hljs-selector-tag">alt</span> <span class="hljs-selector-tag">text</span>" <span class="hljs-selector-tag">src</span>={figure1} /&gt;
</code></pre>
<p>The image will now display with a caption.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_13-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot example of image caption</em></p>
<h4 id="heading-videos">‌Videos</h4>
<p>To caption videos, HTML is a great option. But if you are using markdown, you can embed videos from YouTube and Vimeo using the <code>&lt;iframe&gt;</code> tag. These apps offer in-built caption support so you can enable captions before adding the embed code.</p>
<p>You could also install third-party plugins for this purpose.</p>
<p>Here's another tip: avoid flashing content in your videos as it could lead to seizure triggers. If your video has flashing bright colours, ensure that it does not exceed two times within a second.</p>
<h3 id="heading-add-transcripts-to-audios-and-videos">Add transcripts to audios and videos</h3>
<p>It's a good idea to add transcripts to your audio and video content. Not everyone will want to watch or listen to the content. But they may be curious to know what it is about.</p>
<p>By adding a transcript, you make it easier for anyone to navigate through the content and get the information that they need.</p>
<h4 id="heading-transcript-for-audio">Transcript for audio</h4>
<p>For audio content, you can insert transcripts using HTML. Here's an example:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">audio</span> <span class="hljs-attr">controls</span> <span class="hljs-attr">muted</span>&gt;</span><span class="hljs-comment">&lt;!--Always set your audios to muted--&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">source</span> <span class="hljs-attr">src</span>=<span class="hljs-string">"ringtone.mp3"</span> <span class="hljs-attr">type</span>=<span class="hljs-string">"audio/mpeg"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">source</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">audio</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">code</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Here is a transcription of the text<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span> 
    00:03 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:05 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:08 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:10 = I need to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:11 = I have to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:13 = I should be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:16 = I am going to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:18 = I ought to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:21 = I have to be productive today<span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
    00:23 = Productivity matters to me <span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">br</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">code</span>&gt;</span>
</code></pre>
<p>For markdown documentation sites like Docusaurus, you can create a custom component.‌</p>
<ul>
<li><p>In your <code>src/components</code> folder, create a file named <code>transcript.jsx</code>.</p>
</li>
<li><p>Insert this code:</p>
</li>
</ul>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>; 
<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Transcript</span>(<span class="hljs-params">{ }</span>) </span>{ 
  <span class="hljs-keyword">const</span> [showTranscript, setShowTranscript] = useState(<span class="hljs-literal">false</span>); 
  <span class="hljs-keyword">const</span> toggleTranscript = <span class="hljs-function">() =&gt;</span> { 
    setShowTranscript(!showTranscript); 
  }; 
  <span class="hljs-keyword">return</span> ( 
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">a</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"#"</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{toggleTranscript}</span>&gt;</span> { 
    showTranscript ? 'Hide transcript' : 'View transcript'
    } 
    <span class="hljs-tag">&lt;/<span class="hljs-name">a</span>&gt;</span> {showTranscript &amp;&amp; ( <span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"transcriptText"</span>&gt;</span> (insert your transcript text here) <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span> )} 
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span> 
  ); 
}
</code></pre>
<ul>
<li>Go to your markdown file and import it.</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">Transcript</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/transcript'; 

&lt;<span class="hljs-selector-tag">Transcript</span> /&gt;
</code></pre>
<p>‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_17-6.png" alt="A screenshot of the audio transcript output on a documentation site" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot of the audio transcript output</em></p>
<p>‌<strong>Note:</strong> I added some tweaks to the code to make transcript display optional. You can edit it if you want the transcript to show as the page loads.</p>
<h4 id="heading-transcript-for-video">Transcript for video</h4>
<p>Now for videos, YouTube is a great option. It provides inbuilt transcripts for your videos. So, you can always embed YouTube videos in your docs.</p>
<p>The transcript is in the video description after the main details. The transcript will display with the timestamps when you click the "Show Transcript" button.</p>
<h3 id="heading-add-code-snippets-and-use-the-colour-contrast-technique">Add code snippets and use the colour contrast technique</h3>
<h4 id="heading-how-to-add-code-snippets">How to add code snippets</h4>
<p>Use code blocks within the text to explain code instead of images. You could also use code snippets to showcase the output of your code. Unless it is necessary to add an image, you should use code snippets.</p>
<p>For instance,</p>
<p><code>index.html</code></p>
<pre><code class="lang-html"><span class="hljs-meta">&lt;!DOCTYPE <span class="hljs-meta-keyword">html</span>&gt;</span> 
<span class="hljs-tag">&lt;<span class="hljs-name">html</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">head</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">http-equiv</span>=<span class="hljs-string">"content-type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"text/html; charset=utf-8"</span> /&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>A calculator app<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span> 
        <span class="hljs-tag">&lt;<span class="hljs-name">link</span> <span class="hljs-attr">rel</span>=<span class="hljs-string">"stylesheet"</span> <span class="hljs-attr">href</span>=<span class="hljs-string">"styles.css"</span>/&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">head</span>&gt;</span> 
    <span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span> 
    <span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span> 
<span class="hljs-tag">&lt;/<span class="hljs-name">html</span>&gt;</span>
</code></pre>
<p>This will allow screen readers to read through the code, which they are not able to do with screenshots.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_14-2.png" alt="A screenshot of the above code" width="600" height="400" loading="lazy"></p>
<p><em>A screenshot of the above code</em></p>
<h4 id="heading-colour-contrast-technique">Colour contrast technique</h4>
<p>The colour contrast technique implies using colours that are opposite or heavily contrasting.</p>
<p>For example, using black text on a white background has a high contrast, as opposed to using light brown text on a brown background.</p>
<p>When combining colours, you could use an <a target="_blank" href="http://colorsafe.co/">accessible colour palette like Color Safe</a>.‌</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_15-4.png" alt="Using a pale white colour on a green background gotten from Color Safe" width="600" height="400" loading="lazy"></p>
<p><em>Using a pale white colour on a green background gotten from Color Safe</em></p>
<h3 id="heading-add-translation-options">Add translation options</h3>
<p>There are documentation sites that provide translation options where you can build your docs in multiple languages, websites like Jekyll. <a target="_blank" href="https://leo3418.github.io/collections/multilingual-jekyll-site/add-language-switcher.html">This is an example</a>.</p>
<p>Docusaurus is also another doc site that provides multilingual options using Crowdin or Git.</p>
<ul>
<li><p><a target="_blank" href="https://docusaurus.io/docs/i18n/git">Follow through this guide</a> to set up translation and localization on Docusaurus using Git.</p>
</li>
<li><p><a target="_blank" href="https://docusaurus.io/docs/i18n/crowdin">Follow through this guide</a> to set up translation and localization on Docusaurus using Crowdin.‌</p>
</li>
</ul>
<h3 id="heading-use-accessibility-testing-tools">Use accessibility testing tools</h3>
<p>There are tools you can use to check for errors in accessibility in your docs. Some examples are <a target="_blank" href="https://wave.webaim.org/">WAVE (Web Accessibility Evaluation Tool)</a> and <a target="_blank" href="https://www.deque.com/axe/">AXE (Accessibility Engine)</a>.</p>
<p>Also, you can get the <a target="_blank" href="https://www.nvaccess.org/download/">NVDA(NonVisual Desktop Access) screen reader</a> to test out your content. This software will let you know how the content of your documentation will be perceived by a user using a screen reader.‌</p>
<h3 id="heading-set-up-an-improvement-or-suggestion-box">Set up an improvement or suggestion box</h3>
<p>Finally, it may not be possible to cover the needs of every user. So you could add a suggestion or improvement box, allowing users to send feedback about how you could further improve the content. Hearing firsthand from users can help you know how best to make the docs accessible for them.</p>
<p>To add an improvement box, you could use an external form link that stores the users' inputs or you could set up the suggestion box in the docs.</p>
<h4 id="heading-how-to-add-an-external-form-link-in-docusaurus">How to add an external form link in Docusaurus</h4>
<p>You would need to create a custom component for that.</p>
<ul>
<li><p>Go to <code>src/components</code> folder and create a file <code>feedback.jsx</code>.</p>
</li>
<li><p>Add this code:</p>
</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">React</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-selector-tag">react</span>'; 

<span class="hljs-selector-tag">export</span> <span class="hljs-selector-tag">default</span> <span class="hljs-selector-tag">function</span> <span class="hljs-selector-tag">FeedbackButton</span>({ href }) {
  return ( &lt;a href={href} <span class="hljs-selector-tag">target</span>="_<span class="hljs-selector-tag">blank</span>" <span class="hljs-selector-tag">rel</span>="<span class="hljs-selector-tag">noopener</span> <span class="hljs-selector-tag">noreferrer</span>" &gt; <span class="hljs-selector-tag">Give</span> <span class="hljs-selector-tag">Feedback</span> &lt;/<span class="hljs-selector-tag">a</span>&gt; ); 
};
</code></pre>
<ul>
<li>In your markdown file import it:</li>
</ul>
<pre><code class="lang-css"><span class="hljs-selector-tag">import</span> <span class="hljs-selector-tag">FeedbackButton</span> <span class="hljs-selector-tag">from</span> '<span class="hljs-keyword">@site</span>/src/components/feedbackbutton';
</code></pre>
<ul>
<li>Insert the link</li>
</ul>
<pre><code class="lang-css">&lt;<span class="hljs-selector-tag">FeedbackButton</span> <span class="hljs-selector-tag">href</span>="<span class="hljs-selector-tag">https</span>://<span class="hljs-selector-tag">forms</span><span class="hljs-selector-class">.google</span><span class="hljs-selector-class">.com</span>" /&gt;
</code></pre>
<p>When you run it on your docs, it should showcase a link to Google forms. Google Forms is an example, you could add the link to your company website or server. Here's what it'll look like:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_18-3.png" alt="A feedback link that states &quot;Give feedback&quot; for suggestion or improvement on a docusaurus docs site that leads users to an external site which is Google Forms" width="600" height="400" loading="lazy"></p>
<p><em>A feedback link for suggestion in a docs site</em></p>
<h2 id="heading-summary">Summary</h2>
<p>To follow and implement these accessibility best practices, you can consider creating or using an already made style guide. This can help you consistently implement these practices and make it easier for you and other technical writers on your team.</p>
<p>There are style guides focused on accessibility for technical writers, such as the following:</p>
<ol>
<li><p><a target="_blank" href="https://github.com/heyawhite/tech-writing-tools/blob/main/accessibility/style.md">Accessibility style guide by Heyawhite</a></p>
</li>
<li><p><a target="_blank" href="https://developers.google.com/style/accessibility">Write accessible documentation by Google for developers</a></p>
</li>
<li><p><a target="_blank" href="https://styleguide.mailchimp.com/writing-for-accessibility/">Writing for Accessibility by MailChimp content style guide</a></p>
</li>
</ol>
<p>That sums up my tips about web accessibility practices in writing. I'm a technical writer, and you can reach out to me on <a target="_blank" href="https://www.instagram.com/ezinneanneemilia/">Instagram</a> or hire me via <a target="_blank" href="https://www.upwork.com/freelancers/~013e195fa64f8b3456?mp_source=share">Upwork</a>. Thank you for reading.‌</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ What is DevTestOps? How to Combine DevOps and TestOps to Build Better Products ]]>
                </title>
                <description>
                    <![CDATA[ Technology is always improving, and developers are always trying to find easier and better ways to improve the software. This is how DevOps came to be, and over time DevTestOps emerged as a new strategy. Today, companies like Spotify apply DevTestOps... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-devtestops/</link>
                <guid isPermaLink="false">66d84fe7f6b5e038a1bde7f0</guid>
                
                    <category>
                        <![CDATA[ Devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Software Testing ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ EZINNE ANNE EMILIA ]]>
                </dc:creator>
                <pubDate>Mon, 18 Jul 2022 14:22:13 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2022/07/DEVTESTOPS_1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Technology is always improving, and developers are always trying to find easier and better ways to improve the software. This is how DevOps came to be, and over time DevTestOps emerged as a new strategy.</p>
<p>Today, companies like Spotify apply DevTestOps in software production which makes it easier for them to update, test, and deploy any changes quickly and easily.</p>
<p>In this article, we are going to look at DevTestOps, its objectives, and processes. We'll also look at how to get started with DevTestOps, best practices, and why a company should adopt DevTestOps.</p>
<p>Before we dive into DevTestOps, let’s look at what DevOps and TestOps are and how they work.</p>
<h2 id="heading-what-are-devops-and-testops">What are DevOps and TestOps?</h2>
<p>DevOps is a combination of Development and Operations. DevOps was introduced in the software development life cycle because of the need for continuous product development. It helps teams more easily integrate and deploy software updates.</p>
<p>TestOps involves carrying out large automation test suites across software so that the software is highly efficient with fewer bugs.</p>
<p>Initially, DevOps was introduced in software teams which enabled collaboration across developers and operators only. Then testers carried out tests towards the end of development.</p>
<p>This posed some challenges to the team, though. Especially after working on some software and concluding it was ready for production – only for the testers to run it and discover complex bugs. It was through these challenges that DevTestOps came to be.</p>
<h2 id="heading-what-is-devtestops">What is DevTestOps?</h2>
<p>DevTestOps is a pattern and part of the software development life cycle that includes continuous testing, integration, and deployment.</p>
<p>In DevTestOps, you test the product throughout the different development stages, which helps reduce the number of bugs at later stages.</p>
<p>In DevTestOps, the Development, Testing, and Operations Teams work hand in hand to ensure quality and proper product testing.</p>
<p>This results in quick delivery, with few to no bugs at the end of the software development lifecycle.</p>
<p>DevTestOps came about as an improved version of DevOps with TestOps included. This makes it easier to build, deploy, and develop quality products with fewer bugs.</p>
<h2 id="heading-objectives-of-devtestops">Objectives of DevTestOps</h2>
<p>DevTestOps has objectives that are called manifestos. The manifestos define the goals that you expect to achieve.</p>
<p>According to <a target="_blank" href="https://www.google.com/amp/s/www.mabl.com/blog/the-road-to-devtestops%3fhs_amp=true">mabl.com</a>:</p>
<blockquote>
<p>"There are five manifestos of DevTestOps which include: Continuous testing over testing at the end. Embracing all testing activities over only automated functional testing. Testing what gives value over testing everything. Testing across the team over testing in siloed testing departments. Product coverage over code coverage." (Source: <a target="_blank" href="https://www.google.com/amp/s/www.mabl.com/blog/the-road-to-devtestops%3fhs_amp=true">mabl.com</a>)</p>
</blockquote>
<h2 id="heading-how-devtestops-works">How DevTestOps Works</h2>
<p>There are various stages of the DevTestOps process. These stages are:</p>
<ol>
<li><p><strong>Plan:</strong> In this stage, you define product details and cross-check to make sure everything aligns with the market.</p>
</li>
<li><p><strong>Build:</strong> In this stage, you build the program and upload it to the repository, carry out unit tests, and if you found the program to have no bugs, then it becomes the codebase. You can add possible updates (suggestions or improvements) before moving to the next stage.</p>
</li>
<li><p><strong>Testing:</strong> In this stage, you carry out and analyse all test cases. You can make subsequent updates and test the program again before delivering it and considering it ready for deployment.</p>
</li>
<li><p><strong>Release:</strong> You launch the product and test other written updates before it is added to the codebase.</p>
</li>
<li><p><strong>Monitor:</strong> You constantly check the product for feedback and issues which are handled and updated immediately.</p>
</li>
</ol>
<h2 id="heading-how-to-get-started-with-devtestops">How to Get Started With DevTestOps:</h2>
<p>Many organisations already use DevOps but keep producing buggy software. If you want to switch to DevTestOps to try to reduce the bugs in your code, here are some steps you can follow.</p>
<h3 id="heading-add-continuous-testing-to-yout-devops-roadmap-or-guide">Add continuous testing to yout DevOps roadmap or guide:</h3>
<p>DevTestOps has a similar culture to DevOps except that in this case, you add continuous testing. Testers should become part of the DevOps team so they can test the software immediately after an update.</p>
<h3 id="heading-create-a-devtestops-toolchain">Create a DevTestOps toolchain:</h3>
<p>A toolchain includes all the tools required to implement DevTestOps. For example, your toolchain might comprise tools like Jira, Kubernetes, Selenium, GitHub, Jenkins and more.</p>
<p>You can assign roles to different teams using these tools so they can work effectively with them.</p>
<h3 id="heading-implement-the-tools-in-your-organization">Implement the tools in your organization:</h3>
<p>Next, you'll need to teach teams how to implement these tools and follow the strategies you put in place for software production.</p>
<p>You could add testing roles to each team, which would transform the work culture and encourage collaboration between the developers, testers and operators in each team.</p>
<h3 id="heading-automation">Automation:</h3>
<p>You should apply automation in each of these processes, from the build phase to the deployment phase. This will help all the developers and testers work more efficiently.</p>
<h3 id="heading-make-constant-improvements">Make Constant improvements:</h3>
<p>Finally, you can constantly update the tools and processes to accommodate relevant trends and updates in the technological space.</p>
<h2 id="heading-best-practices-for-devtestops">Best Practices for DevTestOps:</h2>
<p>Here are some best practices you can follow to implement DevTestOps in your team:</p>
<ul>
<li><p>Use the right tools and frameworks for integration, testing, delivery and deployment. This will depend on what works best for the organization.</p>
</li>
<li><p>Apply automation in testing, deployment, and even other stages as well. Automation will help to speed up the process and make it easier for teams to produce faster and meet with deadlines.</p>
</li>
<li><p>All teams should communicate effectively. They should promote collaboration across teams to increase understanding which will increase productivity and eliminate confusion.</p>
</li>
<li><p>The pipeline which comprises continuous integration, testing, delivery and deployment should be monitored always. If you spot a problem, teams can make changes and integrate the updates immediately.</p>
</li>
</ul>
<h2 id="heading-why-should-you-adopt-devtestops">Why Should You Adopt DevTestOps?</h2>
<p>‌There are many reasons to adopt DevTestOps. First, it improves code quality.</p>
<p>It also improves collaboration between developers, testers, and operators. Like in the manifesto, testing is no longer done in siloed testing departments but across each phase.</p>
<p>Additionally, it saves time that is spent on fixing bugs when testing at the end instead of in each stage.</p>
<p>And finally, it makes it easier to perform continuous integration and deployment.‌</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In a world of constant improvements in technology, companies must continually improve their software to meet market standards.</p>
<p>With DevTestOps, it becomes easier for software teams to make updates and improve their products.</p>
<h3 id="heading-resources">Resources:</h3>
<ul>
<li><p><a target="_blank" href="https://www.google.com/amp/s/www.xenonstack.com/insights/devtestops-advantages%3fhs_amp=true">DevOps Advantages And Best Practices | Quick Guide</a></p>
</li>
<li><p><a target="_blank" href="https://www.google.com/amp/s/blog.kms-solutions.asia/an-ultimate-guide-to-devtestops%3fhs_amp=true">What Is DevTestOps And How Can It Transform Agile</a></p>
</li>
<li><p><a target="_blank" href="https://www.google.com/amp/s/katalon.com/resources-center/blog/devtestops-orchestration-agile-teams%3fhs_amp=true">What Is DevOps Orchestration For Agile Teams?</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
