Skip to content

Harden search ranking relevance#29903

Open
harshach wants to merge 26 commits into
mainfrom
harshach/search-ranking-review
Open

Harden search ranking relevance#29903
harshach wants to merge 26 commits into
mainfrom
harshach/search-ranking-review

Conversation

@harshach

@harshach harshach commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator

Describe your changes:

Related to #29853

Fixes search ranking settings parity and hardens the 2.0.0 default ranking behavior so name/identity matches consistently outrank weak usage-heavy matches.

This PR also addresses the open review-comment items from #29853:

  • UI-derived partialName stages now keep .ngram fields.
  • Explore tools toggles have accessible labels and read-only state indicators.
  • Search settings test helper disables ranking through typed POJOs.
  • Stale Table Data Quality page JavaDoc is corrected.

Type of change:

  • Bug fix
  • Improvement

High-level design:

Ranking hardening:

  • exact-stage matching now tries raw query variants and stopword-stripped variants, so names containing stopwords like cost_of_goods_sold can still land in exactName.
  • exact and phrase ranking stages use constant_score so identity-stage precedence is deterministic instead of BM25/idf dependent.
  • tokenCoverage is implemented as per-token coverage wrapped in constant_score, rather than compiling the same as standard multi-match.
  • configured searchFields boosts are honored inside ranked text stages after normalization, keeping stage weight dominant.
  • ranking.signals.fields now gates which term/value functions are applied.
  • default signals are rebalanced: Tier is visible, raw usage is reduced, percentile usage is preferred, and entityStatus gives a small tie-breaker advantage to active/non-deprecated statuses.
  • syntax detection keeps ranked search for pure quoted queries and intra-word hyphenated identifiers.
  • multilingual stopword defaults are populated for de/es/fr/pt/ru/zh/jp/ja.
  • table fqnParts is explicitly mapped as keyword for en/ru; zh/jp already had it.

No schemaChanges.sql change is included. For 2.0.0, fresh/default settings are registered from searchSettings.json; existing beta was manually patched already.

Tests:

Use cases covered

  • Search settings UI derives partialName stages from .ngram name fields instead of analyzed name fields.
  • Explore tools menu exposes read-only, labeled toggle state indicators for ranking details and deleted results.
  • Search settings integration helpers disable ranking through typed POJOs instead of JSON tree mutation.
  • Exact ranking includes raw and stopword-stripped query variants.
  • Ranked search remains enabled for pure quoted and intra-word hyphenated queries.
  • Signal allow-list gates ranking functions.
  • Search field boost configuration contributes to ranked stage field weights.

Unit tests

  • I added unit tests for the new/changed logic.
  • Files updated: SearchSettingsUtils.test.ts, ExploreV1.test.tsx, SearchRankingHelperTest.java, SearchSourceBuilderFactoryTest.java
  • Coverage %: Not measured.

Backend integration tests

  • Existing integration test helpers compile with typed POJO changes.
  • Files updated: SearchSettingsTestHelper.java

Ingestion integration tests

  • Not applicable (no ingestion changes).

Playwright (UI) tests

  • Not applicable (no Playwright workflow changes).
  • Files updated: TableDataQualityPage.java

Manual testing performed

  • PATH=/opt/homebrew/opt/node@22/bin:$PATH yarn test SearchSettingsUtils.test.ts ExploreV1.test.tsx --runInBand
  • UI checkstyle sequence for changed UI files: organize-imports-cli, eslint --fix, prettier --write
  • mvn -pl openmetadata-integration-tests spotless:apply
  • mvn -pl openmetadata-sdk -am -DskipTests install
  • mvn -pl openmetadata-integration-tests -DskipTests test-compile
  • mvn -pl openmetadata-service spotless:apply
  • mvn -pl openmetadata-service -Dtest=SearchRankingHelperTest,SearchSourceBuilderFactoryTest test
  • jq empty openmetadata-service/src/main/resources/json/data/settings/searchSettings.json openmetadata-spec/src/main/resources/elasticsearch/{en,ru,zh,jp}/table_index_mapping.json
  • git diff --check

Not in this PR: P3 click/LTR feedback wiring and a full offline relevance harness. Those need product/data plumbing beyond the 2.0.0 ranking migration/default-settings fix.

UI screen recording / screenshots:

Not attached — UI change is accessibility/state semantics only with no intended visual change.

Checklist:

  • I have read the CONTRIBUTING document.
  • My PR title is Fixes <issue-number>: <short explanation>
  • My PR is linked to a GitHub issue via Fixes #<issue-number> above.
  • I have commented on my code, particularly in hard-to-understand areas.
  • For JSON Schema changes: I updated the migration scripts or explained why it is not needed.
  • For UI changes: I attached a screen recording and/or screenshots above.
  • I have added tests (unit / integration / Playwright as applicable) and listed them above.
  • I have added a test that covers the exact scenario we are fixing.
  • I have added tests around the new logic.

Greptile Summary

This PR hardens search ranking relevance by making exact/phrase stages use constant_score (deterministic boost), introducing per-token TOKEN_COVERAGE queries, wiring signals.fields as an allow-list for term/value boost functions, and rebalancing default signal weights (Tier, entityStatus, percentile-rank usage preferred over raw counts). It also fixes auto-tab selection to prefer the entity type of the top-ranked hit rather than the bucket with the most results, and adds multilingual stopword defaults and fqnParts keyword mappings.

  • Backend ranking: Exact and phrase stages now wrap sub-queries in constant_score for deterministic scoring; TOKEN_COVERAGE is implemented as per-token multi-match; stageFieldWeights normalizes configured boosts into the [0.75, 1.25] range; signals.fields gates which term/value functions run.
  • Frontend auto-tab: fetchEntityData now requests one result from the count query (pageSize: 1, 1-indexed) to identify the top hit's entity type, which findActiveSearchIndex uses as an override over the highest-count bucket.
  • UI accessibility: Explore-tools toggles are marked isReadOnly + excludeFromTabOrder so screen readers and keyboard navigation correctly reflect their state-indicator role.

Confidence Score: 5/5

Safe to merge; changes are well-scoped to search ranking configuration and UI state management with no data mutations or schema changes.

The ranking logic changes are isolated to query-building paths, covered by unit tests (SearchRankingHelperTest, SearchSourceBuilderFactoryTest, ExplorePureUtils.test.ts, ExploreUtils.test.ts), and the only behavioral change visible to users — which tab auto-selects on an unscoped search — is intentional and correct. The dual-implementation duplication and minor count-query inefficiency are style concerns that do not affect correctness.

No files require special attention. The TOKEN_COVERAGE builder in both ElasticSearchSourceBuilderFactory and OpenSearchSourceBuilderFactory is duplicated and should be kept in sync on future changes.

Important Files Changed

Filename Overview
openmetadata-service/src/main/java/org/openmetadata/service/search/SearchRankingHelper.java Adds exactMatchTexts(List), unescapePlainTextQuery, queryTerms, signalFieldEnabled, stageFieldWeights, and helpers; logic is well-tested and handles null/empty edge cases correctly.
openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchSourceBuilderFactory.java Adds constant_score wrapping for EXACT/PHRASE stages, TOKEN_COVERAGE per-token queries, stageFieldWeights for STANDARD/FUZZY, and signals allow-list filtering; the new buildTokenCoverageRankingStageQueryV2 is a near-identical copy of the OpenSearch counterpart.
openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchSourceBuilderFactory.java Parallel to ElasticSearch counterpart — same ranking changes, same TOKEN_COVERAGE duplication; logic is symmetric and correct.
openmetadata-service/src/main/java/org/openmetadata/service/search/SearchSourceBuilderFactory.java Refines containsQuerySyntax to treat intra-word hyphens/plus as plain text and properly propagate escape state; isPureQuotedQuery and isTokenLeadingSyntax helpers are well-reasoned and tested.
openmetadata-service/src/main/resources/json/data/settings/searchSettings.json Rebalances signal weights (Tier boosted, raw usage reduced, percentile-rank preferred), adds entityStatus term boosts and multilingual stopwords; the signals.fields allow-list now includes both weekly and monthly stats fields.
openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx Count query now fetches pageSize:1 with entityType field to discover the top hit's type; applyHitCounts returns {counts, topHitSearchIndex}; the with-tab branch discards the extra data (harmless overhead) while the no-tab branch uses it for auto-selection.
openmetadata-ui/src/main/resources/ui/src/utils/ExplorePureUtils.ts findActiveSearchIndex now prefers topHitIndex and falls back to max-count tab with stable tie-breaking by tab order; behavior change is intentional and well-tested.
openmetadata-ui/src/main/resources/ui/src/pages/ExplorePage/ExplorePageV1.component.tsx Adds autoSelectedSearchIndex state and capture wrappers; passes DATA_ASSET (not derived searchIndex) to fetchDependencies when no tab is selected, preventing spurious re-fetches.
openmetadata-ui/src/main/resources/ui/src/utils/SearchSettingsUtils.ts Adds deriveNgramNameFields so partialName/ngram stages pick .ngram fields; correctly gated by isPrimaryNameField check.
openmetadata-ui/src/main/resources/ui/src/components/ExploreV1/ExploreV1.component.tsx Toggle components inside Explore-tools menu now carry isReadOnly, excludeFromTabOrder, and aria-label attributes for accessibility correctness.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant UI as ExplorePageV1
    participant FE as fetchEntityData
    participant SA as searchAPI
    participant ES as Elasticsearch/OpenSearch

    UI->>FE: fetch(query, tab?, searchIndex)

    alt tab is set
        par Count + Results in parallel
            FE->>SA: countPayload (pageSize:1, fetchSource:true, entityType)
            SA->>ES: DATA_ASSET index agg query (from:0, size:1)
            ES-->>SA: aggregations + 1 hit
            SA-->>FE: applyHitCounts returns discarded topHitSearchIndex
        and
            FE->>SA: resultsQuery(searchIndex)
            SA->>ES: typed index query
            ES-->>SA: hits
            SA-->>FE: searchResults
        end
    else no tab
        FE->>SA: countPayload (pageSize:1, fetchSource:true, entityType)
        SA->>ES: DATA_ASSET index agg query (from:0, size:1)
        ES-->>SA: aggregations + top hit
        SA-->>FE: counts + topHitSearchIndex
        FE->>FE: findActiveSearchIndex(counts, tabsInfo, topHitSearchIndex)
        Note over FE: topHitIndex wins over max-count tab
        FE->>UI: setAutoSelectedSearchIndex(effectiveIndex)
        FE->>SA: resultsQuery(effectiveIndex)
        SA->>ES: effectiveIndex query
        ES-->>SA: hits
        SA-->>FE: searchResults
    end

    FE->>UI: setSearchHitCounts, setSearchResults, setUpdatedAggregations
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant UI as ExplorePageV1
    participant FE as fetchEntityData
    participant SA as searchAPI
    participant ES as Elasticsearch/OpenSearch

    UI->>FE: fetch(query, tab?, searchIndex)

    alt tab is set
        par Count + Results in parallel
            FE->>SA: countPayload (pageSize:1, fetchSource:true, entityType)
            SA->>ES: DATA_ASSET index agg query (from:0, size:1)
            ES-->>SA: aggregations + 1 hit
            SA-->>FE: applyHitCounts returns discarded topHitSearchIndex
        and
            FE->>SA: resultsQuery(searchIndex)
            SA->>ES: typed index query
            ES-->>SA: hits
            SA-->>FE: searchResults
        end
    else no tab
        FE->>SA: countPayload (pageSize:1, fetchSource:true, entityType)
        SA->>ES: DATA_ASSET index agg query (from:0, size:1)
        ES-->>SA: aggregations + top hit
        SA-->>FE: counts + topHitSearchIndex
        FE->>FE: findActiveSearchIndex(counts, tabsInfo, topHitSearchIndex)
        Note over FE: topHitIndex wins over max-count tab
        FE->>UI: setAutoSelectedSearchIndex(effectiveIndex)
        FE->>SA: resultsQuery(effectiveIndex)
        SA->>ES: effectiveIndex query
        ES-->>SA: hits
        SA-->>FE: searchResults
    end

    FE->>UI: setSearchHitCounts, setSearchResults, setUpdatedAggregations
Loading

Reviews (25): Last reviewed commit: "Merge branch 'main' into harshach/search..." | Re-trigger Greptile

@github-actions github-actions Bot added backend safe to test Add this label to run secure Github workflows on PRs labels Jul 9, 2026
@harshach
harshach marked this pull request as ready for review July 9, 2026 19:08
@harshach
harshach requested a review from a team as a code owner July 9, 2026 19:08
Copilot AI review requested due to automatic review settings July 9, 2026 19:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

❌ PR checklist incomplete

This PR cannot be merged until the following are addressed on its linked issue:

  • No GitHub issue is linked. Link an issue in the Development section of the PR (or add Fixes #12345 to the description). For a same-org cross-repo issue, add Fixes open-metadata/<repo>#123 to the description.

The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically.

Maintainers can bypass this check by adding the skip-pr-checks label.

@github-actions

github-actions Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Jest test Coverage

UI tests summary

Lines Statements Branches Functions
Coverage: 65%
65.15% (75728/116225) 48.93% (45129/92219) 49.74% (13653/27447)

@harshach harshach changed the title [codex] Fix search ranking settings parity [codex] Harden search ranking relevance Jul 9, 2026
Copilot AI review requested due to automatic review settings July 9, 2026 20:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings July 9, 2026 21:13
…ng-review

Resolved SystemResourceIT.java conflict by adopting main's canonical-driven
fieldValueBoost assertions (from #30060), which validate against the packaged
searchSettings.json instead of hardcoded factors and therefore hold for this
branch's retuned signal values.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 22 out of 22 changed files in this pull request and generated 2 comments.

Comment on lines +231 to +233
private static boolean isTokenLeadingSyntax(String query, int index) {
return index == 0 || Character.isWhitespace(query.charAt(index - 1));
}
Comment on lines 223 to 231
"[a TO z]",
"-deprecated",
"customer -orders",
"*PII*")

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

pmbrull
pmbrull previously approved these changes Jul 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 21 out of 21 changed files in this pull request and generated 1 comment.

Comment on lines 198 to +202
for (int i = 0; i < query.length(); i++) {
char current = query.charAt(i);
if (isSingleCharacterSyntax(current)
|| isFieldQuerySeparator(query, i)
|| isBooleanOperatorAt(query, i)) {
if (!isEscaped(query, i)
&& (isSingleCharacterSyntax(query, i, pureQuotedQuery)
|| isFieldQuerySeparator(query, i)
|| isBooleanOperatorAt(query, i))) {
A relevance-ranked search query surfaces related entities across several
asset types — e.g. searching a chart's exact name also matches the dashboard
that embeds it. `findActiveSearchIndex` returned the first populated tab in
tab order, so the results panel could open a tab that does not contain the
searched entity (chart name -> Dashboards tab has 1 hit -> chart card absent).

Pick the entity index with the most hits instead, keeping the original tab
order on ties. This restores the behaviour the precise query_string path gave
before the search ranking changes and fixes the "Verify charts are visible in
explore tree" Playwright regression (chart search rendered the embedding
dashboard instead of the chart).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 23 out of 23 changed files in this pull request and generated no new comments.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@gitar-bot

gitar-bot Bot commented Jul 18, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Hardens 2.0.0 search ranking by using constant-score deterministic stages, rebalanced signals, and improved syntax detection to ensure identity matches outrank usage. UI regressions are resolved, and mapping updates for keyword fields are included.

✅ 2 resolved
Bug: Top-hit lookup can throw when _source is absent (NLP path)

📄 openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx:252 📄 openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx:222-229
applyHitCounts reads res.hits.hits[0]?._source.entityType, but the optional chain only guards hits[0], not _source. For the NLP branch the count request runs with fetchSource: false, so hits are returned without a _source field (see formatSearchQueryResponse, which explicitly checks '_source' in hit). Accessing .entityType on an undefined _source throws a TypeError; in the no-tab branch this is caught by handleSearchError, which aborts the results query and shows an error toast, effectively breaking NLP search. Guard the second access as well.

Edge Case: Exact stage feeds raw quoted query, producing unmatchable term variants

📄 openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchSourceBuilderFactory.java:674-688 📄 openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchSourceBuilderFactory.java:1112-1126
buildExactRankingStageQueryV2 now adds originalQuery to the list passed to SearchRankingHelper.exactMatchTexts. For a pure-quoted query (which still reaches the ranked path because containsQuerySyntax no longer treats surrounding quotes as syntax), originalQuery retains its wrapping double quotes, e.g. "customer orders". exactMatchTexts then derives keyword term variants that embed the literal " characters ("customer orders", "customer_orders", etc.). These termQuery clauses run against keyword fields (name/fqnParts) whose indexed values never contain quote characters, so they can never match — harmless but they add dead should-clauses to every exact stage for quoted queries. Consider stripping a single pair of surrounding quotes from originalQuery before building exact-match variants so the intended identity match is produced.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@gitar-bot

gitar-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 2 resolved / 2 findings

Hardens 2.0.0 search ranking by using constant-score deterministic stages, rebalanced signals, and improved syntax detection to ensure identity matches outrank usage. UI regressions are resolved, and mapping updates for keyword fields are included.

✅ 2 resolved
Bug: Top-hit lookup can throw when _source is absent (NLP path)

📄 openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx:252 📄 openmetadata-ui/src/main/resources/ui/src/utils/ExploreUtils.tsx:222-229
applyHitCounts reads res.hits.hits[0]?._source.entityType, but the optional chain only guards hits[0], not _source. For the NLP branch the count request runs with fetchSource: false, so hits are returned without a _source field (see formatSearchQueryResponse, which explicitly checks '_source' in hit). Accessing .entityType on an undefined _source throws a TypeError; in the no-tab branch this is caught by handleSearchError, which aborts the results query and shows an error toast, effectively breaking NLP search. Guard the second access as well.

Edge Case: Exact stage feeds raw quoted query, producing unmatchable term variants

📄 openmetadata-service/src/main/java/org/openmetadata/service/search/elasticsearch/ElasticSearchSourceBuilderFactory.java:674-688 📄 openmetadata-service/src/main/java/org/openmetadata/service/search/opensearch/OpenSearchSourceBuilderFactory.java:1112-1126
buildExactRankingStageQueryV2 now adds originalQuery to the list passed to SearchRankingHelper.exactMatchTexts. For a pure-quoted query (which still reaches the ranked path because containsQuerySyntax no longer treats surrounding quotes as syntax), originalQuery retains its wrapping double quotes, e.g. "customer orders". exactMatchTexts then derives keyword term variants that embed the literal " characters ("customer orders", "customer_orders", etc.). These termQuery clauses run against keyword fields (name/fqnParts) whose indexed values never contain quote characters, so they can never match — harmless but they add dead should-clauses to every exact stage for quoted queries. Consider stripping a single pair of surrounding quotes from originalQuery before building exact-match variants so the intended identity match is produced.

Options

Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Compact
gitar display:verbose         

Was this helpful? React with 👍 / 👎 | Gitar

@sonarqubecloud

Copy link
Copy Markdown

@sonarqubecloud

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backend safe to test Add this label to run secure Github workflows on PRs skip-pr-checks Bypass PR metadata validation check

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants