Skip to content

Comments

feat: validate grafanaDep with semver#515

Merged
s4kh merged 7 commits intomainfrom
feat-validate-semver
Feb 20, 2026
Merged

feat: validate grafanaDep with semver#515
s4kh merged 7 commits intomainfrom
feat-validate-semver

Conversation

@s4kh
Copy link
Contributor

@s4kh s4kh commented Feb 16, 2026

Validate plugin.json -> dependencies.grafanaDependency using SemVer constraint.
Ignores schema validation for dependencies.grafanaDependency.

break
}

pluginJsonBytes, _ := os.ReadFile(metadataPath)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this stage, we know plugin.json file exists so no need to check for that.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the file fails to open or to be read? I'd still keep the error check just in case

for _, desc := range result.Errors() {
// we validate grafanaDependency at line 91-100,
// so we ignore the error from schema validation
if strings.Contains(desc.Field(), "grafanaDependency") {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried removing from the schema, but we have to read the schema and iterate through and find the grafanaDependency object and remove. Ignoring the returned error seemed simple so went with it.

@s4kh s4kh self-assigned this Feb 16, 2026
@s4kh s4kh requested a review from academo February 16, 2026 15:32
if err := json.Unmarshal(pluginJsonBytes, &data); err == nil {
fmt.Println(data.Dependencies.GrafanaDependency)
_, err = version.NewConstraint(data.Dependencies.GrafanaDependency)
fmt.Println(err)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this

if pluginJsonBytes != nil {
var data metadata.Metadata
if err := json.Unmarshal(pluginJsonBytes, &data); err == nil {
fmt.Println(data.Dependencies.GrafanaDependency)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove print

_, err := Analyzer.Run(pass)
require.NoError(t, err)
require.Len(t, interceptor.Diagnostics, 2)
require.Equal(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: validate that the schema is not reporting grafanaDependency as it used to be.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

now the new error message is checked in the main_test.go

)
require.Equal(
t,
"plugin.json: (root): Additional property invalid is not allowed",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need this validation here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is to check combination of schema and grafanaDependency.

@grafana-plugins-platform-bot grafana-plugins-platform-bot bot moved this from 📬 Triage to 🔬 In review in Grafana Catalog Team Feb 16, 2026
@s4kh s4kh force-pushed the feat-validate-semver branch from a3f0e0a to 4734a26 Compare February 16, 2026 16:20
Copy link
Member

@xnyo xnyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some small comments but the rest LGTM to me. I don't think this will conflict with #513 as they currently do two different things, but since the analyzer in #513 is called grafanaDependency we can maybe move this check over there instead once merged? (before cutting a release because the analyzer name will change if we move a check from one analyzer to another)

break
}

pluginJsonBytes, _ := os.ReadFile(metadataPath)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the file fails to open or to be read? I'd still keep the error check just in case

@s4kh s4kh force-pushed the feat-validate-semver branch from 4734a26 to ca6cf1b Compare February 16, 2026 16:36
@s4kh s4kh requested review from academo and xnyo February 16, 2026 17:04
Copy link
Member

@xnyo xnyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went through this again considering also #513. I think we should merge this PR first, but we should make some changes before merging. My proposal is the following:

  • Move the grafanaDependency check via the semver library in a separate grafanadependency analyzer, similar to #513. I would be fine with keeping the semver range check in the metadatavalid analyzer, but we need the extra checks in #513 (mostly just for our internal teams as sometimes they tend to forget the pre-release constraint -> deploy to cloud -> cause an incident because the version is "not supported". It never happens with community plugins since pretty much nobody uses on-prem "rolling" releases off main), so I think a dedicated analyzer is more suited, to keep those grafanaDependency-related checks close to each other
  • Since the proposal is to move those more robust checks with the semver library in a different analyzer, I think we should remove the grafanaDependency error filtering done here:
    // we validate grafanaDependency at line 91-100,
    // so we ignore the error from schema validation
    if strings.Contains(desc.Field(), "grafanaDependency") || strings.Contains(desc.Description(), "grafanaDependency") {
    errLen -= 1
    continue
    }
    , unless it will conflict with the semver library check. I don't know if they will conflict with each other, but ideally they shouldn't: I see the regex as a first level of validation (weaker), and the semver library as a second one (more robust). If for some reason there are instances where the regex/schema check fails, but it should pass when fed into the semver library, I think we should change the regex instead of filtering out the error. If we decide to move the semver check into a dedicated analyzer, the filtering done in metadatavalid (like in this PR) will become messy because it would reference checks done on a separate grafanadependency analyzer. Moreover, if the user uses a config file that disables grafanadependency but keeps metadatavalid, the checks on the grafanaDependency field are skipped completely. I'd still keep a "simpler" check in metadatavalid and a proper one in a brand new analyzer

Once we merge this PR, I will rework #513 also considering your previous feedback (this PR is in a better state than #513, we're better off unblocking this one first)

What are your thoughts on this? @s4kh @academo

@s4kh
Copy link
Contributor Author

s4kh commented Feb 17, 2026

I think the main problem with validating grafanaDependency in the metadatavalid check is the complexity of regex. Semver constraint can get pretty complex, and we need to adjust the regex every time - or sometimes regex fails but the other dedicated check passes or vice versa. And since we will be already using the semver validator for the grafanaDependency do we need to validate in the metadatavalid? I'll move it to the separate analyzer.

@s4kh s4kh force-pushed the feat-validate-semver branch from cfe2d0a to 79ae153 Compare February 17, 2026 19:49
name: "complex but valid grafanaDependency constraint",
pluginJSON: `{
"id": "test-org-app",
"dependencies": { "grafanaDependency": ">=11.6.11 <12 || >=12.0.10 <12.1 || >=12.1.7 <12.2 || >=12.2.5" }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using github.com/Masterminds/semver/v3 v3.4.0 cause hashicorp/go-version treats this as invalid. Grafana treats as valid -> grafana/grafana#118090

@s4kh s4kh force-pushed the feat-validate-semver branch 2 times, most recently from 6fca874 to 71f0efe Compare February 17, 2026 20:29
@s4kh s4kh requested a review from xnyo February 18, 2026 14:43
@s4kh s4kh force-pushed the feat-validate-semver branch from 71f0efe to 309ccac Compare February 19, 2026 14:31
Copy link
Member

@xnyo xnyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one small comment, the rest LGTM! Great job! 🙌

)

func TestGrafanaDependency(t *testing.T) {
for _, tc := range []struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add test cases for:

  • Empty grafanaDependency
  • Missing grafanaDependency (if that makes sense, since there's also the schema validation)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Got it. Added the tests. Unmarshal succeeds and NewConstraint returns error - improper constraint thus same title message is returned

@s4kh s4kh merged commit b0f0069 into main Feb 20, 2026
8 checks passed
@s4kh s4kh deleted the feat-validate-semver branch February 20, 2026 14:07
@github-project-automation github-project-automation bot moved this from 🔬 In review to 🚀 Shipped in Grafana Catalog Team Feb 20, 2026
s4kh added a commit that referenced this pull request Feb 20, 2026
* feat: validate grafanaDep with semver

* test: add parent key

* test: error msg change

* ref: log the error

* ref: extract to separate analyzer, use semver

* test: empty or missing grafana dep

* chore: retrigger ci
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 🚀 Shipped

Development

Successfully merging this pull request may close these issues.

3 participants