Skip to content

Commit

Permalink
Docs: Describe compatibility strategy in best-practices doc (#1494)
Browse files Browse the repository at this point in the history
Co-authored-by: Joseph Perez <45749060+josmperez@users.noreply.github.com>
  • Loading branch information
sunker and josmperez authored Jan 30, 2025
1 parent 13cdfd9 commit 5c59534
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 38 deletions.
56 changes: 20 additions & 36 deletions docusaurus/docs/e2e-test-a-plugin/ci.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,30 @@ import FEPluginNPM from '@snippets/plugin-e2e-fe-plugin-workflow.npm.md';
import FEPluginYarn from '@snippets/plugin-e2e-fe-plugin-workflow.yarn.md';
import FEPluginPNPM from '@snippets/plugin-e2e-fe-plugin-workflow.pnpm.md';

# CI workflow
This article walks through the process of running end-to-end tests against a matrix of Grafana versions.

You can use a CI workflow to run end-to-end tests that allow you to continuously check for breakages. We recommend using the following GitHub workflows for every PR in your GitHub repository to run end-to-end tests against a range of Grafana versions.
## Why run end-to-end tests against a matrix of Grafana versions

Due to Grafana’s [dependency sharing mechanism](../key-concepts/manage-npm-dependencies.md), many plugin-related issues only emerge at runtime. For example, if a plugin invokes a function, component or class that is unavailable in the Grafana runtime environment, any page loading that part of the plugin will crash. These runtime-specific issues are beyond the scope of unit tests but can be effectively identified through end-to-end testing.

To maintain reliability and compatibility, plugin developers must regularly perform end-to-end tests across all supported Grafana versions. The `e2e-versions` GitHub Action simplifies this process by automatically resolving supported Grafana versions based on your plugin's `grafanaDependency`, while also including Grafana's main development branch. Integrating this Action into your CI workflows ensures your plugin remains stable and compatible with both older and newer versions of Grafana, giving you confidence in its functionality across versions."

## The e2e-versions Action

The `e2e-versions` GitHub Action generates a matrix of Grafana image names and versions for use in end-to-end testing a Grafana plugin within a GitHub workflow. The Action supports two modes:

- **`plugin-grafana-dependency:`** This mode resolves the most recent `grafana-dev` image and returns all the latest patch releases of Grafana Enterprise since the version specified as `grafanaDependency` in the `plugin.json` file. To prevent the initiation of too many jobs, the output is capped at 6 versions. This is the default mode.
- **`version-support-policy:`** In this mode, the action resolves versions based on Grafana's plugin compatibility support policy. It retrieves the latest patch release for each minor version within the current major Grafana version. Additionally, it includes the most recent release for the latest minor version of the previous major Grafana version.

For detailed information on configuring the `inputs`, visit the `e2e-versions` [GitHub page](https://github.com/grafana/plugin-actions/tree/main/e2e-version).

## Example workflows

All Grafana plugins created with `grafana/create-plugin` version 4.7.0 or later automatically include end-to-end tests against a Grafana version matrix as part of their `ci.yml` workflow. If your plugin was created with an earlier version, you can use the following example workflows to set up and run end-to-end tests with a Grafana version matrix in a separate GitHub workflow:

:::note

These are generic examples based on frontend and backend plugins. You may need to alter or remove some of the steps in the `playwright-tests` job before using it in your plugin.
The following examples are generic and based on frontend and backend plugins. Depending on the specifics of your plugin, you may need to modify or remove certain steps in the `playwright-tests` job before integrating them into your plugin’s workflow.

:::

Expand Down Expand Up @@ -55,39 +72,6 @@ queryString="current-package-manager"
/>
</details>

## The e2e-versions Action

These example workflows have a job called `Resolve Grafana images` that uses the [e2e-version](https://github.com/grafana/plugin-actions/tree/main/e2e-version) Action to resolve a list of Grafana images. For every image returned, a new job is started that builds the plugin, starts Grafana, and runs the end-to-end tests.

The Action supports two modes:

- `plugin-grafana-dependency`
- `version-support-policy`.

### Use the plugin-grafana-dependency mode

The `plugin-grafana-dependency` mode is the default, so if you don't specify a value for the `version-resolver-type` input parameter, this is the resolver that will be used.

This mode returns the most recent grafana-dev image. Additionally, it returns all the latest patch releases of Grafana Enterprise since the version that was specified as `grafanaDependency` in the [plugin.json](../reference/metadata.md). To avoid starting too many jobs, the output is capped at 6 versions.

![plugin-grafana-dependency mode](/img/e2e-version-plugin-dependency.png)

### Use the version-support-policy mode

Except for resolving the most recent `grafana-dev` image, the `version-support-policy` mode resolves versions according to Grafana's plugin compatibility support policy. Specifically, it retrieves the latest patch release for each minor version within the current major version of Grafana. Additionally, it includes the most recent release for the latest minor version of the previous major Grafana version.

![Grafana version support policy](/img/e2e-version-version-support-policy.png)

To use the `version-support-policy` mode, you need to specify the `version-resolver-type` input argument like in this example:

```yml
- name: Resolve Grafana E2E versions
id: resolve-versions
uses: grafana/plugin-actions/e2e-version
with:
version-resolver-type: version-support-policy
```
## Playwright report

The end-to-end tooling generates a Playwright HTML test report for every Grafana version that is being tested. In case any of the tests fail, a Playwright trace viewer is also generated along with the report. The `Upload artifacts` step in the example workflows uploads the report to GitHub as an artifact.
Expand Down
21 changes: 20 additions & 1 deletion docusaurus/docs/get-started/best-practices.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,26 @@ Is something missing from this list? [Let us know](https://github.com/grafana/pl
- **To generate dynamic apps, consider using [Grafana Scenes](https://grafana.com/developers/scenes/).**
- **Consider contributing a [UI extension](../key-concepts/ui-extensions)** - UI extensions can help a user to discover your app in context and continue a given workflow. Additionally, if your app provides context that can be used in other apps, then create an extension point to allow these apps to do so, with no further changes required in your app.

## Publishing a plugin
## Publish a plugin

- **Add a GitHub badge** - Follow [these steps](https://grafana.com/blog/2024/06/06/6-tips-to-improve-your-grafana-plugin-before-you-publish/#tip-4-add-dynamic-badges-to-your-readme) to help users find your plugin using GitHub badges.
- **Add workflow automation** - If your plugin is available on GitHub, consider [adding the GitHub workflows](../get-started/set-up-development-environment.mdx#set-up-github-workflows) for plugin development to your repository.

## Manage plugin compatibility

In the Grafana plugin ecosystem, plugin compatibility with specific Grafana versions is determined by the semantic versioning range defined in the `grafanaDependency` property of the plugin's `plugin.json` file. Plugin authors must carefully select a version range that balances broad compatibility with the need for manageable maintenance efforts.

### Unique challenges in plugin development

Grafana plugins are a rather unusual piece of software in the sense that many npm dependencies used during compilation are replaced with different versions at runtime. For more details, refer to [Frontend NPM dependencies in a Grafana plugin](../key-concepts/manage-npm-dependencies.md). This runtime substitution can cause crashes if a plugin relies on APIs that are unavailable in the active Grafana environment. As a result, managing compatibility is a critical and complex aspect of plugin development.

### Best practices for managing plugin compatibility

To ensure robust and reliable plugins, follow these best practices:

- **Adopt the latest plugin APIs:** Using the latest plugin API versions allows developers to leverage new Grafana features and ensures alignment with the platform's evolving capabilities. It also encourages regular maintenance and updates of plugins and its dependencies.
- **Maintain a single development branch:** Aim to maintain a single branch for the entire range of Grafana versions supported by the plugin (as specified in the `grafanaDependency`). This approach reduces the maintenance burden and aligns with practices used in the Grafana plugin catalog.
- **Manage backward compatibility with runtime checks:** To utilize new Grafana features while maintaining compatibility with older versions, implement conditional logic that verifies feature availability at runtime. For guidance, see [Manage backwards compatibility with runtime checks](../how-to-guides/runtime-checks.md).
<!-- Uncomment when this article is written - **Manage backward compatibility by using the compatibility packge:** -->
<!-- Uncomment when this article is written - **Manage backward compatibility by bundling `grafana/ui`:** -->
- **Perform end-to-end testing using a Grafana version matrix:** Grafana's dependency-sharing mechanism can cause many plugin-related issues to appear only at runtime. These issues can be effectively identified by running end-to-end smoke tests across a matrix of Grafana versions defined in the plugin's `plugin.json` file. Regularly testing the plugin against both older supported versions and Grafana's main development branch ensures backward and forward compatibility. This approach allows plugin maintainers to verify functionality with current and upcoming Grafana releases, maintaining reliability and readiness for future updates.
2 changes: 1 addition & 1 deletion docusaurus/docs/how-to-guides/runtime-checks.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ keywords:

# Manage backwards compatibility with runtime checks

Most Grafana NPM dependencies used in plugins are shared with the Grafana application at runtime, as detailed in the Manage NPM Dependencies article. To take advantage of new Grafana features in plugins while maintaining compatibility with older versions, plugin authors need to implement conditional logic that checks for feature availability during runtime. Failing to account for backward compatibility can result in plugin crashes and a poor user experience.
Most Grafana NPM dependencies used in plugins are shared with the Grafana application at runtime, as detailed in the [Manage NPM Dependencies](../key-concepts/manage-npm-dependencies.md) article. To take advantage of new Grafana features in plugins while maintaining compatibility with older versions, plugin authors need to implement conditional logic that checks for feature availability during runtime. Failing to account for backward compatibility can result in plugin crashes and a poor user experience.

The method for performing these runtime checks varies depending on the feature and how it is made available to plugin developers. The following examples demonstrate best practices for handling these scenarios effectively.

Expand Down

0 comments on commit 5c59534

Please sign in to comment.