paranext / paranext-core

Electron client, extension host, and C# library for Paranext
https://paranext.github.io/paranext-core/
MIT License
14 stars 3 forks source link

Design fine-grained versioning for `papi` #235

Open tjcouch-sil opened 1 year ago

tjcouch-sil commented 1 year ago

The items on the papi needs to be versioned. Functions, data types, import statements, etc. All interaction needs to be versioned. We should probably also define some rules for when to bump versions.

We also should design how to best version the wiki documentation.

We need to design extension versioning as well for extensions depending on other extensions.

lyonsil commented 1 year ago

FWIW, ChatGPT says:

When it comes to designing versioning for TypeScript and JavaScript modules, there are several best practices you can follow to ensure smooth compatibility and maintainability. Here are some recommendations:

  1. Semantic Versioning (SemVer): Follow the principles of SemVer for versioning your modules. SemVer consists of three parts: MAJOR.MINOR.PATCH. Increment the MAJOR version when you make incompatible changes, the MINOR version when you add functionality in a backwards-compatible manner, and the PATCH version when you make backwards-compatible bug fixes.

  2. Git Version Tagging: Utilize Git tags to mark specific versions of your modules. Whenever you release a new version, create a corresponding Git tag with the version number. This allows you to easily track and reference specific releases in your codebase.

  3. Package Managers: If you are using a package manager like npm (Node Package Manager) or yarn, leverage their versioning features. These tools provide commands to manage module versions, publish new releases, and handle dependencies.

  4. Peer Dependencies: Clearly define and manage your module's dependencies, especially peer dependencies. Peer dependencies indicate the compatibility requirements for other modules that may be used alongside your module. Make sure to specify accurate version ranges for peer dependencies to avoid compatibility issues.

  5. Changelogs: Maintain a detailed changelog for each version of your module. Changelogs provide information about the changes made in each release, including bug fixes, new features, and breaking changes. This helps users understand the impact of upgrading to a new version and allows for easier debugging.

  6. Release Notes and Documentation: Alongside your changelog, provide release notes and updated documentation for each version. Clearly explain any breaking changes and provide migration guides if necessary. This assists developers in understanding the changes and adapting their code accordingly.

  7. Testing and Continuous Integration (CI): Implement a robust testing strategy to ensure the stability and compatibility of your modules across different versions. Automated testing, coupled with continuous integration and deployment (CI/CD) pipelines, can help catch potential issues early and prevent regressions.

  8. Deprecation and Sunset Policy: Clearly communicate your deprecation and sunset policy. When you plan to deprecate or remove certain features or modules, provide advance notice and establish a timeline for the deprecation process. This allows users to plan and adapt their code accordingly.

By following these guidelines, you can create a solid versioning strategy for your TypeScript and JavaScript modules, enabling seamless upgrades and better compatibility for your users.

These all seem pretty good to me. Item 1 has some good rules for when to bump versions that matches my experience in the past. Sometimes there is a fourth component which is a build date or date/time that gets used mostly when working with release candidates.

Is there a reason we wouldn't want all of the core repo to carry a unified version?

Versioning a wiki to align with code versioning can be achieved through various approaches. Here are a few common methods:

  1. Git Repository: Store your wiki content in a separate Git repository alongside your codebase. This allows you to leverage the same version control system for both code and documentation. You can create branches, tags, and commits in the wiki repository to correspond with code versions, making it easy to track changes and maintain synchronization.

  2. Documentation as Code: Treat your wiki content as code and version it alongside your codebase within the same repository. Write your documentation using a markup language like Markdown or reStructuredText. By keeping your documentation files in the code repository, you can track changes and version them using the same version control system.

  3. Documentation Branches: Create separate branches in your code repository dedicated to documentation. You can have branches like "master" for the main code and "docs" for the documentation. Each branch can have its own versioning scheme, allowing you to manage and release documentation versions independently.

  4. Release Tags: Use Git tags or release tags to mark specific versions of your codebase, and create corresponding tags for your wiki. This way, you can link each release of your code with a specific version of the wiki. Users can then access the wiki content corresponding to the version of the code they are using.

  5. Documentation Versioning Tools: There are specialized tools available for versioning documentation, such as Read the Docs (https://readthedocs.org/). These tools allow you to create separate versions of your documentation and associate them with specific code versions. They often integrate with popular version control systems like Git and provide a dedicated interface for managing and browsing different versions of your documentation.

  6. Changelog Integration: Include a link to the relevant version of the wiki in your code's changelog or release notes. This ensures that users can easily find the corresponding documentation for each code version.

It's important to choose a method that suits your team's workflow and requirements. Whichever approach you adopt, ensure that your documentation is easily accessible and clearly tied to specific code versions. This enables developers to access the relevant information and helps maintain consistency between the codebase and the accompanying documentation.

This seems a little less obvious to me. I think @FoolRunning has used https://readthedocs.org/ for some scripture burrito work.

tjcouch-sil commented 1 year ago

I tried to get more specific with ChatGPT regarding a JavaScript extension API, but I don't think it was really getting it. After some clarifications about what the api isn't, it mostly suggested SEMVER (I guess for the whole entire api) and hard versioning in the specification, but it didn't give any code examples. Maybe they could look something like this:

  1. import papi from 'papi-frontend-1.0.3' or 'papi-frontend-1.x.x' or something like that
  2. import papi from 'papi-frontend' (and track which version of the papi it wants based on what's listed in the manifest.json or maybe package.json)
  3. In use: papi.v1.dataProvider.get
  4. In use: papi.dataProvider.get.v1 or papi.dataProvider.v1.get or papi.dataProvider.getV1 or something

Seems like they might all have pretty similar complexity in terms of avoiding code duplication, but 1-3 would probably have most/all of the duplication elimination code in the papi service, whereas 4 would probably put it on the service. Would be interesting to contemplate this and figure out a good solution. I like the feel of 2 right now, but I feel like 4 would probably be easiest to implement and understand.

FoolRunning commented 1 year ago

This seems a little less obvious to me. I think @FoolRunning has used https://readthedocs.org/ for some scripture burrito work.

@lyonsil, Yes, that is correct. It does work well for versioning documentation. You can see it in use for Burrido.Bible (version selector is on the bottom-left).