--- ---

Development Process (General)

General development process for DocOps Lab projects

DocOps Lab projects follow a consistent, if always progressing, architecture and development/release process.

This guide focuses on contributing code to projects and products, be it functional code, data, or documentation.

More generally, dev contributors will most likely need to use the docopslab-dev tool to coordinate development and testing tasks. Each repository has its own Rakefile with custom tasks, but each also incorporates the common (upstream) docopslab-dev library for extending the rake tasks.

Prerequisites

Technologies Overview

DocOps Lab projects are primarily Ruby gems, usually with associated Docker images that provide proper environments for the CLI associated with the project gem.

Ruby is used mainly because of its excellent AsciiDoc tooling through Asciidoctor, with an accompanying preference for Jekyll static-site generator and Liquid templating language, all of which are Ruby native.

Docker is employed by internal developers and end users of DocOps Lab tooling alike, to reduce if not eliminate the Ruby maintenance overhead.

Required Tools

If you are brand new to the world of code, Git, and GitHub, DocOps Lab will soon have resources aimed precisely at your experience level. For now, some experience with these tools is assumed.

Must-haves
Should-haves
  • GitHub CLI (gh)

  • a code editor that supports Ruby, AsciiDoc, and YAML
    (Try VS Code if you don’t have a preference yet.)

Ruby Environment

Ruby dependencies are managed through Bundler using each project’s Gemfile/.gemspec definitions.

A proper Ruby environment and all common (cross-project) development dependencies are supplied in the docopslab/dev Docker image. Containers run from this image provide unified linting, git hooks, and development tooling used by most DocOps Lab codebases.

These quality-control tools are also built into all GitHub repos via GH Actions workflows, local availability is not required just to work on or contribute to a DocOps Lab codebase.

See DocOps Lab Dev-tooling Setup for comprehensive setup details if you are initializing a new DocOps Lab project.

Repository State

Development is done on development trunk branches named like dev/x.y, where x is the major version and y is the minor.

To start development on a new release version:

git checkout main
git pull origin main
git checkout -b dev/1.2
git checkout -b chore/bump-version-1.2.0
git commit -am "Bumped version attributes in README"
git checkout dev/1.2
git merge chore/bump-version-1.2.0
git push -u origin dev/1.2

Development Procedures

Work on feature or fix branches off the corresponding dev/x.y trunk.

git checkout dev/1.2
git checkout -b feat/add-widget
… implement …
git add .
git commit -m "feat: add widget"
git push -u origin feat/add-widget
gh pr create --base dev/1.2 --title "feat: add widget" --body "Adds a new widget to the dashboard."
Branch naming conventions
  • feat/…​ for new features OR improvements

  • fix/…​ for bugfixes

  • chore/…​ for version bumps and sundry tasks with no product impact

  • epic/…​ for large features or changes that span releases

Commit Message Conventions

Description (first line) conventions
  • Use present-tense descriptive verbs (“adds widget”, not “added” or “add”)

  • feat: …​ for new features OR improvements

  • fix: …​ for bugfixes

  • chore: …​ for version bumps and sundry tasks with no product impact

  • docs: …​ for documentation changes

  • test: …​ for test code changes

  • refactor: …​ for code restructuring with no functional changes

  • style: …​ for formatting, missing semi-colons, etc; no functional changes

  • perf: …​ for performance improvements

  • auto: …​ for changes to CI/CD pipelines and build system

Body conventions
  • Use the body to explain what and why vs. how.

  • Reference issues and pull requests as needed.

  • Use bullet points (- text) and paragraphs as needed for clarity.

  • Do not hard-wrap lines, but do:

    • use 1-sentence per line

    • keep sentences short

See DocOps Lab Git Commits Style Guide for detailed commit message conventions.

Merging Changes

Squash-merge branches back into dev/x.y:

git checkout dev/1.2
git checkout -b feat/add-widget
… implement …
git add .
git commit -m "feat: add widget"
git merge --squash feat/add-widget
git commit -m "feat: add widget"
git push origin dev/1.2

Delete merged branches.

Dev Branch Rules

  • Always branch from dev/x.y.

  • Always squash-merge into dev/x.y.

  • Never merge directly into main.

Documentation Practices

A critical part of development at DocOps Lab is writing and maintaining good documentation. After all, docs are our business.

Standard (User) Docs

Standard documentation is mainly done in AsciiDoc.

AsciiDoc files are found in the _docs/ or docs/ directory.

A _docs/ directory exists for internal documentation. These files may be published in some form, but they should be distinct from docs intended to help end users.

A docs/ directory exists for user-facing documentation files. These are published distinctly.

For complete documentation styles guidance, see DocOps Lab Documentation Style Guide.

Initially, all developer and user-facing documentation is maintained in the README.adoc file, simply for convenience. Prior to a 1.0.0 release, most user-facing and usually some developer-facing documentation should be moved from the README to the docs/ and _docs/ directories.

In GitHub Issues, use needs:docs to designate work items that will require standard internal or user-facing documentation.

Inline Documentation

Some documentation can be accessed through the product (such as --help menus), which is also often sourced inside product files (rather than dedicated doc files).

APIs

  • Use YARD for Ruby code documentation.

  • Document all public methods and classes.

  • API docs are published at https://gemdocs.org/PROJECT_NAME/.

CLIs

Most DocOps Lab CLIs provide --help and even --man flags, for a basic menu or a manpage related to the given command.

These will be designated and documented in the project’s README.adoc file.

Release History

DocOps Lab projects use ReleaseHx to maintain release notes and changelogs.

Each project should have a .config/releasehx.yml file.

There are also labels available to designate a GitHub issue’s status in the documentation announcing the release it belongs to.

  • Use needs:note to designate an issue that should be detailed for end users.

  • Use changelog to designate an issue that should be included in the changelog (just the summary).

Release notes are added to the main GitHub issue body as appended Markdown. At the end of the note body, add:

## Release Note

One or two sentences summarizing the change for end users.
Markdown formatting *will* be converted to AsciiDoc during drafting.

See DocOps Lab Release Process (General) for more on generating the release history.

Test Development Process

All DocOps Lab projects should include comprehensive test suites following consistent patterns.

Testing itself is documented in DocOps Lab Testing & Specifications, but this section focuses on creating and maintaining tests as part of development.

Adding Tests for New Features

When implementing new functionality:

  1. Create corresponding tests alongside feature implementation

  2. Follow existing patterns established in spec_helper.rb

  3. Use descriptive test names that clearly indicate what is being tested

  4. Group related tests in logical contexts and describe blocks

  5. Add cleanup procedures for any temporary files or resources

Test File Template

Use this template for new test files:

require_relative 'spec_helper'

RSpec.describe YourModule do
  let(:temp_dir) { create_temp_dir }
  let(:sample_data) { create_temp_yaml_file(your_sample_data) }

  after do
    FileUtils.rm_rf(temp_dir) if Dir.exist?(temp_dir)
    File.unlink(sample_data) if File.exist?(sample_data)
  end

  describe "core functionality" do
    context "when given valid input" do
      it "processes data correctly" do
        result = YourModule.process(sample_data)
        expect(result).to be_a(Hash)
        expect(result).to have_key('expected_field')
      end
    end

    context "when given invalid input" do
      it "handles errors gracefully" do
        expect { YourModule.process(nil) }.to raise_error(ArgumentError)
      end
    end
  end
end

Test Data Integration

Projects should leverage demo data for realistic testing:

Demo Directory Usage

Utilize rich sample data from ../projectname-demo/ directories. Validate configuration files, mapping files, and sample data sets.

Helper Methods

Implement helper methods in spec_helper.rb for:

  • create_temp_yaml_file(content) - Generate temporary YAML files

  • create_temp_json_file(content) - Generate temporary JSON files

  • create_temp_dir - Create temporary directories

  • sample_*_data - Provide realistic test data structures

Cleanup Procedures

Ensure all tests clean up after themselves:

after do
  FileUtils.rm_rf(temp_dir) if Dir.exist?(temp_dir)
  File.unlink(temp_file) if File.exist?(temp_file)
end

Test Maintenance Best Practices

Standard Rake Testing Tasks

All Ruby gem projects with tests should implement these standard Rake tasks in their Rakefile:

bundle exec rake rspec

Run RSpec test suite using the standard pattern matcher.

bundle exec rake cli_test

Validate command-line interface functionality. May test basic CLI loading, help output, version information.

bundle exec rake yaml_test

Validate YAML configuration files and data structures. Should test all project YAML files for syntax correctness.

bundle exec rake pr_test

Comprehensive test suite for pre-commit and pull request validation. Typically includes: RSpec tests, CLI tests, YAML validation.

bundle exec rake install_local

Build and install the project locally for testing.

Note that non-gem projects may have some or all of these tasks, as applicable.

Test Organization

Unit Tests

Test individual methods and classes in isolation. Focus on edge cases, error conditions, and expected behavior.

Integration Tests

Test workflows that span multiple components. Validate data flow through processing pipelines.

Validation Tests

Test configuration loading, file format compliance. Validate that all demo/example files are syntactically correct.

Performance Considerations

  • Use temporary files/directories that are automatically cleaned up.

  • Avoid testing with large datasets unless specifically testing performance.

  • Use mocking/stubbing for external API calls and expensive operations.

  • Group related tests to minimize setup/teardown overhead.

Error Testing

  • Test both expected errors and edge cases.

  • Verify error messages are helpful and actionable.

  • Test error recovery and graceful degradation.

  • Validate that errors don’t leave systems in inconsistent states.

Continuous Integration

Pre-commit Testing

Before committing changes:

rake pr_test  # Run comprehensive test suite

Pull Request Validation

Ensure all pull requests:

  1. Pass the complete test suite (rake pr_test)

  2. Include tests for new functionality

  3. Update existing tests when modifying behavior

  4. Maintain or improve test coverage

  5. Include integration tests for workflow changes

Release Testing

Before any release:

  1. Ensure any new tests are added.

  2. Run automated tests.

    rake install_local    # Build and install locally
    rake pr_test          # Complete validation
  3. Manually test key workflows.

  4. Update or add any documentation.

Common Problems

Test File Cleanup

Tests should automatically clean up temporary files. Manual cleanup: rm -rf /tmp/projectname_test_*

Missing Dependencies

Ensure bundle install has been run. Check that all required gems are in Gemfile.

Demo Data Access

Verify that demo directories exist and are accessible. Ensure tests are run from the correct working directory.

Debug Mode

Run tests with verbose output for troubleshooting:

bundle exec rspec --format documentation --backtrace
rake pr_test  # Often includes verbose options

AI Usage Policy

DocOps Lab does not share unreviewed AI output with the outside world, period. Such matter is kept from public code repositories, documentation sites, and the rest of our public footprint.

As a general rule of thumb, everything we produce that is affected by AI must have been enhanced or improved by the AI’s contributions.

By this, we mean AI output should be at least as good as or better than output we would be able to produce without those tools. We do not release code or content that is inferior, compared to what we can produce ourselves, in terms of:

  • accuracy

  • clarity

  • logic

  • style

  • humanity

  • security

  • maintainability

  • compliance with standards or best practices

For the complete policy, see DocOps Lab Generative "AI" Guidance.