docs: def build(source_dir, target_dir, package_name=None, version_number=None):
      '''
      Create a release of a MicroDrop plugin source directory in the target
      directory path.
  
      Skip the following patterns:
  
       - ``bld.bat``
       - ``.conda-recipe/*``
       - ``.git/*``
  
      .. versionchanged:: 0.24.1
          Remove temporary archive after extraction.
  
          Change directory into source directory before running ``git archive``.
  
      .. versionchanged:: 0.25
          Add optional :data:`version_number` argument.
  
      Parameters
      ----------
      source_dir : str
          Source directory.
      target_dir : str
          Target directory.
      package_name : str, optional
          Name of plugin Conda package (defaults to name of :data:`target_dir`).
      version_number : str, optional
          Package version number.
  
          If not specified, assume version package exposes version using
          `versioneer <https://github.com/warner/python-versioneer>`_.
      '''
      source_dir = ph.path(source_dir).realpath()
      target_dir = ph.path(target_dir).realpath()
      target_dir.makedirs_p()
      source_archive = source_dir.joinpath(source_dir.name + '.zip')
      if package_name is None:
          package_name = str(target_dir.name)
      logger.info('Source directory: %s', source_dir)
      logger.info('Source archive: %s', source_archive)
      logger.info('Target directory: %s', target_dir)
      logger.info('Package name: %s', package_name)
  
      # Export git archive, which substitutes version expressions in
      # `_version.py` to reflect the state (i.e., revision and tag info) of the
      # git repository.
      original_dir = ph.path(os.getcwd())
      try:
          os.chdir(source_dir)
          sp.check_call(['git', 'archive', '-o', source_archive, 'HEAD'],
                        shell=True)
      finally:
          os.chdir(original_dir)
  
      # Extract exported git archive to Conda MicroDrop plugins directory.
      with zipfile.ZipFile(source_archive, 'r') as zip_ref:
          zip_ref.extractall(target_dir)
      # Extraction is complete.  Remove temporary archive.
      source_archive.remove()
  
      # Delete Conda build recipe from installed package.
      target_dir.joinpath('.conda-recipe').rmtree()
      # Delete Conda build recipe from installed package.
      for p in target_dir.files('.git*'):
          p.remove()
  
      # Write package information to (legacy) `properties.yml` file.
      original_dir = ph.path(os.getcwd())
      try:
          os.chdir(source_dir)
          if version_number is None:
              # Assume versioneer is being used for managing version.
              import _version as v
  
              version_info = {'version': v.get_versions()['version'],
                              'versioneer': v.get_versions()}
          else:
              # Version number was specified explicitly.
              version_info = {'version': version_number}
      finally:
          os.chdir(original_dir)
  
      # Create properties dictionary object (cast types, e.g., `ph.path`, to
      # strings for cleaner YAML dump).
      properties = {'package_name': package_name,
                    'plugin_name': str(target_dir.name)}
      properties.update(version_info)
  
      with target_dir.joinpath('properties.yml').open('w') as properties_yml:
          # Dump properties to YAML-formatted file.
          # Setting `default_flow_style=False` writes each property on a separate
          # line (cosmetic change only).
          yaml.dump(properties, properties_yml, default_flow_style=False)