From 7d0e7fdec2738be1bbe42b4182aaf36e697a5002 Mon Sep 17 00:00:00 2001 From: redcatbear Date: Wed, 10 Jun 2026 09:22:40 +0200 Subject: [PATCH 1/2] #51: Added Marketplace metadata. --- .../oft-spec-driven-development/SKILL.md | 22 ++ .github/workflows/build.yml | 5 + .github/workflows/release.yml | 5 + README.md | 6 + build.gradle.kts | 38 ++- doc/changes/changelog.md | 1 + doc/changes/changes_0.8.1.md | 15 ++ ...lete-marketplace-facing-plugin-metadata.md | 235 ++++++++++++++++++ doc/design/architecture_decisions.md | 76 ++++-- doc/design/building_block_view.md | 10 + doc/design/deployment_view.md | 2 + doc/marketplace/description.html | 13 + doc/marketplace/release-checklist.md | 12 + doc/system_requirements.md | 23 ++ gradle.properties | 2 +- src/main/resources/META-INF/plugin.xml | 6 +- .../OftMarketplaceMetadataTest.java | 92 +++++++ 17 files changed, 530 insertions(+), 33 deletions(-) create mode 100644 doc/changes/changes_0.8.1.md create mode 100644 doc/changesets/51-complete-marketplace-facing-plugin-metadata.md create mode 100644 doc/marketplace/description.html create mode 100644 doc/marketplace/release-checklist.md create mode 100644 src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java diff --git a/.agents/skills/oft-spec-driven-development/SKILL.md b/.agents/skills/oft-spec-driven-development/SKILL.md index 3dec71c..0c91b8c 100644 --- a/.agents/skills/oft-spec-driven-development/SKILL.md +++ b/.agents/skills/oft-spec-driven-development/SKILL.md @@ -187,12 +187,34 @@ Out of scope: - [ ] Decide if and which part of the version needs to be incremented. Use semantic versioning rules (breaking change updates major, feature updates minor, documentation, fixes and refactoring update fix number) - [ ] Raise the version to (this is a release) - [ ] Write the changelog entry for +- [ ] Determine the bundled OpenFastTrace library version from the Gradle dependency metadata +- [ ] Write the bundled OpenFastTrace version into the fixed changelog location for - [ ] Update release date to today - [ ] Ensure that issue list contains the GitHub issue number and title ``` Keep verification items concrete. Do not leave them as generic "run tests" placeholders when the quality requirements demand more specific checks. +## Changelog Rules + +Every release changelog must state the OpenFastTrace library version bundled +with the plugin. Determine it from the resolved Gradle dependency for +`org.itsallcode.openfasttrace:openfasttrace`, not from memory. + +Always write it in the same place: immediately after the release summary text +and before the first issue-category section such as `## Features`, +`## Documentation`, or `## Build Maintenance`. Use the heading +`## Bundled OpenFastTrace` and the content `OpenFastTrace `. + +When plugin descriptor metadata is in scope, prefer copying this changelog +section into plugin `changeNotes`, because JetBrains displays change notes in +Marketplace and in the Plugins settings dialog. Keep source release notes in +Markdown; if plugin `changeNotes` require HTML, render the active release note +to generated HTML with Pandoc during the build instead of storing the source +changelog as HTML. Use the plugin `description` only if the maintainers want the bundled +OpenFastTrace version visible as longer-lived installed-plugin overview text +independent of the current release notes. + ## Issue Intake Rules When the user provides a tracker link: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 861dd0e..3ab3736 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -30,6 +30,11 @@ jobs: distribution: temurin java-version: 21 + - name: Install Pandoc + run: | + sudo apt-get update + sudo apt-get install --yes pandoc + - name: Set up Gradle uses: gradle/actions/setup-gradle@v6 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 751b0f6..6c402ef 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -32,6 +32,11 @@ jobs: distribution: temurin java-version: 21 + - name: Install Pandoc + run: | + sudo apt-get update + sudo apt-get install --yes pandoc + - name: Set up Gradle uses: gradle/actions/setup-gradle@v6 with: diff --git a/README.md b/README.md index ee41050..0f66e05 100644 --- a/README.md +++ b/README.md @@ -96,6 +96,8 @@ You need a JetBrains IDE based on the IntelliJ Platform (for example, IntelliJ I ### Development Dependencies To build and test from source, use the project’s configured Gradle wrapper and a compatible JDK. +To package the plugin with generated Marketplace change notes, install Pandoc +on `PATH` or set `PANDOC` to the executable path. ## Icon Assets @@ -126,6 +128,10 @@ committed Gradle lock file: ./gradlew --write-locks dependencies ``` +Marketplace-facing descriptor metadata is maintained in +[doc/marketplace](doc/marketplace), with Pandoc generating change-note HTML +from the active Markdown entry under [doc/changes](doc/changes/changelog.md). + Example OFT files for manual testing are available under `examples/` in this project. For a guided live demonstration, use the script in [doc/demo/plugin-demo.md](doc/demo/plugin-demo.md) with the isolated example project in [doc/demo/example](doc/demo/example). diff --git a/build.gradle.kts b/build.gradle.kts index 1aacb0e..b8104bf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,9 @@ import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask +import org.gradle.api.tasks.PathSensitivity import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent import org.gradle.api.tasks.bundling.Zip +import org.gradle.api.tasks.Exec import org.gradle.jvm.toolchain.JavaLanguageVersion import org.gradle.testing.jacoco.plugins.JacocoTaskExtension import org.jetbrains.intellij.platform.gradle.TestFrameworkType @@ -24,6 +26,33 @@ plugins { } val pluginVersion = providers.gradleProperty("version") +val marketplaceDescription = providers.fileContents( + layout.projectDirectory.file("doc/marketplace/description.html") +).asText +val activeReleaseNotes = layout.projectDirectory.file("doc/changes/changes_${pluginVersion.get()}.md") +val marketplaceChangeNotesFile = layout.buildDirectory.file("generated/marketplace/change-notes-${pluginVersion.get()}.html") +val pandocExecutable = providers.environmentVariable("PANDOC").orElse("pandoc") +// [bld->dsn~marketplace-change-notes-use-pandoc~1] +val renderMarketplaceChangeNotes = tasks.register("renderMarketplaceChangeNotes") { + description = "Renders the active Markdown release notes to plugin descriptor HTML with Pandoc." + group = "build" + inputs.file(activeReleaseNotes).withPathSensitivity(PathSensitivity.RELATIVE) + outputs.file(marketplaceChangeNotesFile) + executable = pandocExecutable.get() + args( + "--from=markdown-auto_identifiers", + "--to=html", + "--wrap=none", + "--output=${marketplaceChangeNotesFile.get().asFile.absolutePath}", + activeReleaseNotes.asFile.absolutePath + ) + doFirst { + outputs.files.singleFile.parentFile.mkdirs() + } +} +val marketplaceChangeNotes = providers.fileContents( + marketplaceChangeNotesFile +).asText group = "org.itsallcode.openfasttrace" version = pluginVersion.get() @@ -96,13 +125,16 @@ dependencies { intellijPlatform { buildSearchableOptions = false + // [bld->dsn~marketplace-plugin-metadata~1] pluginConfiguration { id = "org.itsallcode.openfasttrace-intellij-plugin" name = "OpenFastTrace" version = pluginVersion + description = marketplaceDescription + changeNotes = marketplaceChangeNotes vendor { - name = "Itsallcode.org" + name = "itsallcode.org" email = "opensource@itsallcode.org" url = "https://itsallcode.org/" } @@ -143,6 +175,10 @@ tasks { archiveBaseName.set("OpenFastTrace") } + named("patchPluginXml") { + dependsOn(renderMarketplaceChangeNotes) + } + withType().configureEach { revision = "release" gradleReleaseChannel = "current" diff --git a/doc/changes/changelog.md b/doc/changes/changelog.md index 3977f78..683fa74 100644 --- a/doc/changes/changelog.md +++ b/doc/changes/changelog.md @@ -1,5 +1,6 @@ # Changelog +* [0.8.1](changes_0.8.1.md) * [0.8.0](changes_0.8.0.md) * [0.7.0](changes_0.7.0.md) * [0.6.0](changes_0.6.0.md) diff --git a/doc/changes/changes_0.8.1.md b/doc/changes/changes_0.8.1.md new file mode 100644 index 0000000..635da68 --- /dev/null +++ b/doc/changes/changes_0.8.1.md @@ -0,0 +1,15 @@ +# OpenFastTrace IntelliJ Plugin 0.8.1, released 2026-06-10 + +Version 0.8.1 improves the metadata shown by JetBrains plugin surfaces. Before installing or updating the plugin, users can now see a clearer overview of what OpenFastTrace support does in the IDE and read the current release notes from the maintained project changelog. + +The plugin description now focuses on the everyday OpenFastTrace workflows in JetBrains IDEs: authoring requirements in project files, tracing requirement chains down to implementation and tests, and debugging broken chains from the IDE. + +The packaged plugin descriptor also carries the project website, `itsallcode.org` vendor metadata, compatibility baseline, and change notes rendered from the active release notes. + +## Bundled OpenFastTrace + +OpenFastTrace 4.5.0 + +## Documentation + +* #51: Complete Marketplace-facing plugin metadata diff --git a/doc/changesets/51-complete-marketplace-facing-plugin-metadata.md b/doc/changesets/51-complete-marketplace-facing-plugin-metadata.md new file mode 100644 index 0000000..40a5bbe --- /dev/null +++ b/doc/changesets/51-complete-marketplace-facing-plugin-metadata.md @@ -0,0 +1,235 @@ +# GH-51 Complete Marketplace-facing plugin metadata + +## Goal + +Complete the plugin metadata that JetBrains Marketplace and the IDE Plugin +Manager read from the packaged plugin descriptor, so users see a clear +OpenFastTrace plugin description, current change notes, and useful project +links before installing or updating the plugin. + +## Scope + +In scope: + +* Add Marketplace-facing description text that explains the plugin value and + main workflows clearly, with developers as the primary audience. +* Populate plugin change notes from the active release notes or another + maintained project source. +* Configure website, vendor, and source/project links where the IntelliJ + Platform Gradle Plugin, `plugin.xml`, and JetBrains Marketplace metadata + support them. +* Review the plugin name, vendor, version, and compatibility metadata against + JetBrains Marketplace listing guidance. +* Prove that `buildPlugin` produces a plugin ZIP whose patched descriptor + contains the expected Marketplace-facing metadata. + +Out of scope: + +* Changing plugin runtime behavior. +* Creating Marketplace screenshots, videos, or paid listing assets. +* Uploading or publishing the plugin to JetBrains Marketplace. +* Rebranding the plugin or changing its stable plugin ID. +* Adding new runtime dependencies to render metadata. +* Marketing-oriented sales copy. + +## Design References + +* [GitHub Issue #51](https://github.com/itsallcode/openfasttrace-intellij-plugin/issues/51) +* [System Requirements](../system_requirements.md) +* [Deployment View](../design/deployment_view.md) +* [Building Block View](../design/building_block_view.md) +* [Design Decisions](../design/architecture_decisions.md) +* [Quality Requirements](../design/quality_requirements.md) +* [JetBrains Marketplace Listing Best Practices](https://plugins.jetbrains.com/docs/marketplace/best-practices-for-listing.html) +* [IntelliJ Platform Gradle Plugin Extension](https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-extension.html) +* [Plugin Configuration File](https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html) + +## Strategy + +Treat this as a user-visible packaging and listing change, not a runtime +feature change. JetBrains Marketplace extracts the plugin name, website link, +description, and change notes from `plugin.xml`, and the IntelliJ Platform +Gradle Plugin can patch descriptor values such as `description`, +`changeNotes`, `version`, `vendor`, and `ideaVersion` during the build. + +Keep the descriptor metadata source-controlled and maintainable. Prefer the +existing `intellijPlatform.pluginConfiguration` block as the single build-time +patching point for metadata that the Gradle plugin supports. Keep any +descriptor-only fields, such as the root `idea-plugin` website URL, in +`src/main/resources/META-INF/plugin.xml` if no Gradle DSL property supports +them. If JetBrains only supports a source-code link through Marketplace admin +metadata rather than the packaged descriptor, document that as a release +checklist item instead of adding unsupported XML. + +Render the active project release notes into the descriptor change notes with +Pandoc so this can be automated from the existing maintained Markdown release +documentation without custom conversion code. + +Keep the listing tone sober and project-focused. This is an open-source plugin, +so the description should explain what users get without sales language. + +## Metadata Decisions + +Use the following user-confirmed metadata targets for implementation: + +* Plugin name: `OpenFastTrace` +* First description sentence: "Author requirements directly in your project and + trace them all the way down to your implementation and tests without leaving + your IDE." +* Audience order: developers first, followed by requirement engineers, quality + engineers, technical writers, and other OpenFastTrace users. +* Main workflows to emphasize: authoring requirements, running traces, and + debugging broken requirement chains. +* Website URL: `https://github.com/itsallcode/openfasttrace-intellij-plugin` +* Source code URL: `https://github.com/itsallcode/openfasttrace-intellij-plugin` +* Issue tracker URL: + `https://github.com/itsallcode/openfasttrace-intellij-plugin/issues` +* Vendor display name: `itsallcode.org` +* Vendor email: keep `opensource@itsallcode.org` +* Vendor URL: keep `https://itsallcode.org/` +* Change notes source: render `doc/changes/changes_.md` to generated + HTML with Pandoc so release automation can reuse the maintained Markdown + changelog. +* Compatibility: keep `ideaVersion.sinceBuild = "261"` and no explicit + `untilBuild`. +* Marketplace wording: avoid sales claims and keep the OSS tone sober. + +## Task List + +- [x] Create and checkout a new Git branch `documentation/51-complete-marketplace-facing-plugin-metadata` + +### Requirements And Design + +- [x] Add or update `doc/system_requirements.md` with a user-visible plugin + distribution requirement for Marketplace and IDE Plugin Manager metadata, + covering description, change notes, relevant links, and descriptor + identity metadata +- [x] Add acceptance scenarios for displaying useful Marketplace-facing + metadata from the packaged plugin descriptor after `buildPlugin` +- [x] Stop and ask user for a review of the system requirements +- [x] Update `doc/design/deployment_view.md` with the packaged descriptor + metadata expected in the plugin ZIP and the maintained source for + description and change notes +- [x] Update `doc/design/building_block_view.md` with a build/distribution + design item that owns descriptor metadata patching through Gradle and + static descriptor fields +- [x] Update `doc/design/architecture_decisions.md` with the Pandoc build-tool + decision for Markdown-to-HTML change-note rendering +- [x] Keep runtime design coverage to one scenario per `dsn` item, or use OFT + forwarding where the deployment/build layer adds no new behavior +- [x] Stop and ask user for a review of the design + +### Implementation + +- [x] Replace the current short source `plugin.xml` description with a + Marketplace-ready description source that starts with a concise English + summary and then describes authoring requirements, running traces, and + debugging broken requirement chains for developers first, followed by + requirement engineers, quality engineers, technical writers, and other + OpenFastTrace users +- [x] Configure `intellijPlatform.pluginConfiguration.description` from the + maintained description source so the patched descriptor contains the + Marketplace-facing description +- [x] Configure `intellijPlatform.pluginConfiguration.changeNotes` from the + active `doc/changes/changes_.md` release notes so the workflow + can be automated from the maintained changelog +- [x] Render the active Markdown release notes with Pandoc during descriptor + patching instead of maintaining custom Markdown-to-HTML conversion logic +- [x] Configure the descriptor website URL through the supported `plugin.xml` + or Gradle mechanism with the GitHub repository URL +- [x] Configure Marketplace source-code and issue-tracker links to the GitHub + repository and GitHub issues page where JetBrains supports them; otherwise + record them as Marketplace admin-panel release tasks +- [x] Set or keep the plugin name as `OpenFastTrace` +- [x] Set the vendor display name to `itsallcode.org` while keeping the current + vendor email and URL +- [x] Review `version`, `ideaVersion.sinceBuild`, and absence of an + unnecessary `untilBuild` against JetBrains compatibility guidance, then + keep the current compatibility stance unless that review finds a concrete + descriptor problem +- [x] Add or update OFT build and implementation coverage tags for the new + design items +- [x] Avoid adding third-party runtime or build dependencies unless the design + review explicitly approves them + +### Verification + +- [x] Add or update automated tests for maintained metadata source files where + practical, including checks that required description and change-note + files exist and are not blank +- [x] Run `./gradlew --warning-mode=all test` +- [x] Run `./gradlew --warning-mode=all traceRequirements` +- [x] Run `./gradlew --warning-mode=all check buildPlugin` +- [x] Inspect the built plugin ZIP and its main plugin JAR to confirm the + patched `META-INF/plugin.xml` contains the expected name, version, + vendor, website URL, description, change notes, and compatibility + metadata +- [x] Confirm the Marketplace description follows JetBrains listing guidance: + the confirmed first-summary text, sober OSS wording, developer-first + audience order, useful workflow bullets, and no screenshots or media + embedded in the descriptor +- [x] Run `./gradlew --warning-mode=all verifyPlugin` +- [x] Keep path coverage at or above the documented 80 percent threshold +- [x] Keep the OpenFastTrace trace clean for `feat`, `req`, `scn`, `dsn`, + `impl`, `utest`, `itest`, and build artifact types in scope +- [x] Keep the dependency policy unchanged, or document and approve any + exception before implementation +- [ ] Keep the SonarQube Cloud quality gate green after CI analysis + +`./gradlew --warning-mode=all test` passes. + +`./gradlew --warning-mode=all traceRequirements` passes. + +`./gradlew --warning-mode=all check buildPlugin` passes and produces +`build/distributions/OpenFastTrace-0.8.1.zip`. + +Inspecting `META-INF/plugin.xml` from the plugin main JAR inside the built ZIP +confirms the descriptor contains the GitHub project URL, `OpenFastTrace` name, +`0.8.1` version, `itsallcode.org` vendor, `since-build="261"` with no +`until-build`, Marketplace description, and change notes rendered from +`doc/changes/changes_0.8.1.md`. + +`./gradlew --warning-mode=all verifyPlugin` passes. The verifier marks the +plugin compatible with `IU-261.25134.95` and `IU-262.7132.23` and still reports +the existing experimental `BackgroundUpdateHighlightersUtil` API usage in +`OftHighlightingPass`. + +### Update User Documentation + +- [x] Update `README.md` only where needed to keep the maintained metadata + source, project links, and release documentation consistent +- [x] Update the active changelog/release notes so Marketplace change notes have + a current source that includes GH-51 and explains that users get a clearer + Marketplace and IDE Plugin Manager overview before installing or updating + the plugin +- [x] Add a release checklist note for Marketplace admin-only links such as + source code or issue tracker if JetBrains does not support those links in + the descriptor + +## Version And Changelog Update + +- [x] Check if the current version mentioned in the build scripts and code + parameters is the same as the latest GitHub release +- [x] Raise the version to `0.8.1` because this is a documentation/packaging + patch release and `0.8.0` is already the latest GitHub release as of + 2026-06-10 +- [x] Write the changelog entry for `0.8.1` +- [x] Word the GH-51 changelog entry from the user's perspective: the plugin now + presents clearer overview metadata and release notes in JetBrains plugin + surfaces, making it easier to understand what the plugin does before + installing or updating it +- [x] Determine the bundled OpenFastTrace library version from the Gradle + dependency metadata +- [x] Write the bundled OpenFastTrace version into the fixed changelog location + for `0.8.1` +- [x] Update the release date to 2026-06-10 or the actual implementation date +- [x] Ensure that the issue list contains `#51: Complete Marketplace-facing + plugin metadata` + +Current `gradle.properties` version is `0.8.1`; latest GitHub release is +`0.8.0`, published on 2026-06-09. This is a patch release. + +`./gradlew dependencyInsight --dependency org.itsallcode.openfasttrace:openfasttrace --configuration runtimeClasspath` +reports `org.itsallcode.openfasttrace:openfasttrace:4.5.0`, selected by +dependency locking. `doc/changes/changes_0.8.1.md` contains +`## Bundled OpenFastTrace` followed by `OpenFastTrace 4.5.0`. diff --git a/doc/design/architecture_decisions.md b/doc/design/architecture_decisions.md index b9b9a64..984969c 100644 --- a/doc/design/architecture_decisions.md +++ b/doc/design/architecture_decisions.md @@ -51,12 +51,48 @@ Needs: bld Tags: Build, Gradle +### How Does The Build Render Marketplace Change Notes? + +The project needs readable source release notes and HTML change notes in the patched plugin descriptor. The conversion must be reliable enough for release automation while keeping the Gradle build script maintainable. + +This decision is architecture-relevant because it impacts: + +* build-tool prerequisites for local and CI packaging +* long-term maintenance cost of release metadata generation +* consistency between the maintained Markdown changelog and bundled descriptor + HTML + +We considered the following alternatives: + +1. Custom Markdown-to-HTML converter in the Gradle build script. + + This avoids a separate executable dependency, but it makes the build own Markdown parsing behavior and grows custom logic for a format that already + has mature tooling. + +1. Use Pandoc as a build-time executable for Markdown-to-HTML rendering. + + This keeps the source release notes in Markdown and delegates conversion to a maintained document conversion tool. The tradeoff is an explicit packaging prerequisite in local release environments and CI. + +#### Marketplace Change Notes Use Pandoc +`dsn~marketplace-change-notes-use-pandoc~1` + +The Gradle build renders the active Markdown release notes to plugin descriptor HTML with Pandoc during descriptor patching and plugin packaging. + +Rationale: + +Pandoc reduces project-specific build logic and avoids maintaining a partial Markdown renderer in `build.gradle.kts`. The executable is a build-time tool only; it does not add a plugin runtime dependency. + +Comment: + +Local builds resolve `pandoc` from `PATH` by default and can use the `PANDOC` environment variable to point to a custom executable location. CI and release jobs install Pandoc before running Gradle packaging tasks. + +Needs: bld + +Tags: Build, Marketplace, Pandoc + ### How Does the Project Keep Gradle Dependency Metadata Predictable? -The project needs predictable Gradle dependency resolution for static analysis -and reproducible local and CI builds. It also needs a lightweight way to check -whether newer dependency, build-plugin, or Gradle versions are available without -making ordinary builds fail when an update exists. +The project needs predictable Gradle dependency resolution for static analysis and reproducible local and CI builds. It also needs a lightweight way to check whether newer dependency, build-plugin, or Gradle versions are available without making ordinary builds fail when an update exists. This decision is architecture-relevant because it impacts: @@ -69,41 +105,29 @@ We considered the following alternatives: 1. Use Gradle dependency verification metadata only. - This would verify artifact integrity, but it would require reviewing and - maintaining checksums for each resolved artifact. The project explicitly does - not want that review burden at this stage. + This would verify artifact integrity, but it would require reviewing and maintaining checksums for each resolved artifact. The project explicitly does not want that review burden at this stage. -1. Use Gradle dependency locking and a custom version-check task. +2. Use Gradle dependency locking and a custom version-check task. - This would keep the dependency set predictable, but a custom version-check - task would add project-specific Gradle logic for behavior that already has a - maintained plugin solution. + This would keep the dependency set predictable, but a custom version-check task would add project-specific Gradle logic for behavior that already has a maintained plugin solution. -1. Use Gradle dependency locking and the Gradle Versions Plugin. +3. Use Gradle dependency locking and the Gradle Versions Plugin. - This keeps normal dependency resolution locked through Gradle's built-in - mechanism and delegates update discovery to a maintained build plugin that + This keeps normal dependency resolution locked through Gradle's built-in mechanism and delegates update discovery to a maintained build plugin that can be run on demand by maintainers. #### Gradle Dependency Maintenance Uses Locks And Versions Plugin `dsn~gradle-dependency-maintenance-uses-locks-and-versions-plugin~1` -The Gradle build uses dependency locking for predictable dependency resolution -and the Gradle Versions Plugin for on-demand dependency, build-plugin, and -Gradle wrapper update reports. +The Gradle build uses dependency locking for predictable dependency resolution and the Gradle Versions Plugin for on-demand dependency, build-plugin, and Gradle wrapper update reports. Rationale: -Gradle dependency locking satisfies the need for stable resolved dependency -versions without enabling full dependency verification metadata. The Gradle -Versions Plugin is an approved build-only dependency for GH-45 and avoids -custom version-check logic in the build script. +Gradle dependency locking satisfies the need for stable resolved dependency versions without enabling full dependency verification metadata. The Gradle Versions Plugin is an approved build-only dependency for GH-45 and avoids custom version-check logic in the build script. Comment: -The version-check task is informational and stays outside the standard `check` -lifecycle. Available updates change over time, so update discovery must not -make normal local or CI builds unstable. +The version-check task is informational and stays outside the standard `check` lifecycle. Available updates change over time, so update discovery must not make normal local or CI builds unstable. Needs: bld @@ -125,11 +149,11 @@ We considered the following alternatives: This preserves immediate feedback, but OSS Index quota, authentication, and service availability issues can block development without revealing anything about the project's dependency security state. -1. Keep OSS Index in the build but make audit failures non-fatal. +2. Keep OSS Index in the build but make audit failures non-fatal. This avoids blocked builds, but it keeps a fragile build integration without a strict enforcement benefit. -1. Remove OSS Index from the Gradle build and rely on GitHub Dependabot alerts. +3. Remove OSS Index from the Gradle build and rely on GitHub Dependabot alerts. This removes the immediate build-time vulnerability gate, but it keeps vulnerability monitoring in GitHub without making every build depend on OSS Index availability. diff --git a/doc/design/building_block_view.md b/doc/design/building_block_view.md index bd7aabe..bb5d264 100644 --- a/doc/design/building_block_view.md +++ b/doc/design/building_block_view.md @@ -227,6 +227,16 @@ Covers: Needs: bld, itest +### Marketplace Plugin Metadata +`dsn~marketplace-plugin-metadata~1` + +The plugin distribution metadata is produced into the patched `META-INF/plugin.xml` descriptor during the Gradle build. Build configuration owns Gradle-supported descriptor fields such as plugin name, version, vendor, compatibility baseline, description, and change notes, while the source descriptor owns static fields that the IntelliJ Platform Gradle Plugin does not patch. Description text stays sober and developer-first, and change notes are rendered to HTML with Pandoc from the maintained Markdown release changelog for the active project version. + +Covers: +- `scn~show-marketplace-metadata-in-jetbrains-plugin-surfaces~1` + +Needs: bld, itest + ### Trace Configuration Integration `dsn~trace-configuration-integration~1` diff --git a/doc/design/deployment_view.md b/doc/design/deployment_view.md index fa74d41..c286e2f 100644 --- a/doc/design/deployment_view.md +++ b/doc/design/deployment_view.md @@ -42,3 +42,5 @@ Network access is not part of the normal processing path. In the MVP, network ac ## Packaged Plugin Resources The plugin distribution includes JetBrains plugin logo SVG assets in the plugin main JAR under `META-INF`. The default logo resource is `META-INF/pluginIcon.svg`; if the default logo is not sufficiently visible on dark backgrounds, the distribution also includes `META-INF/pluginIcon_dark.svg`. + +The plugin distribution also contains Marketplace-facing metadata in the patched `META-INF/plugin.xml` descriptor. The Gradle build keeps the descriptor version, vendor, compatibility baseline, description, and Pandoc-rendered change notes aligned with the project metadata and release documentation. Static descriptor fields remain in `src/main/resources/META-INF/plugin.xml` when the IntelliJ Platform Gradle Plugin does not provide a supported patching property for them. diff --git a/doc/marketplace/description.html b/doc/marketplace/description.html new file mode 100644 index 0000000..07f5489 --- /dev/null +++ b/doc/marketplace/description.html @@ -0,0 +1,13 @@ +

Author requirements directly in your project and trace them all the way down to your implementation and tests without leaving your IDE.

+ +

OpenFastTrace adds IDE support for developers who maintain OpenFastTrace specifications next to source code. It also supports requirement engineers, quality engineers, technical writers, and other OpenFastTrace users working in the same project.

+ +
    +
  • Author OpenFastTrace requirement, scenario, design, implementation, and test items with syntax highlighting and live templates.
  • +
  • Navigate between specification item declarations, Covers: references, and source-side coverage tags.
  • +
  • Complete existing specification item IDs while editing requirement chains.
  • +
  • Run OpenFastTrace checks for the whole project or for configured run configurations.
  • +
  • Inspect trace results in IntelliJ's Test Runner UI and navigate to the source of broken requirement chains.
  • +
+ +

The plugin uses the project files already opened in the IDE and does not require a separate OpenFastTrace command-line installation for normal tracing workflows.

diff --git a/doc/marketplace/release-checklist.md b/doc/marketplace/release-checklist.md new file mode 100644 index 0000000..bce5889 --- /dev/null +++ b/doc/marketplace/release-checklist.md @@ -0,0 +1,12 @@ +# JetBrains Marketplace Release Checklist + +The packaged plugin descriptor owns metadata that JetBrains can read from `META-INF/plugin.xml`, including the plugin name, version, vendor, compatibility baseline, website URL, description, and change notes. + +When publishing or updating the JetBrains Marketplace listing, keep these Marketplace admin fields aligned with the repository: + +* Website URL: `https://github.com/itsallcode/openfasttrace-intellij-plugin` +* Source code URL: `https://github.com/itsallcode/openfasttrace-intellij-plugin` +* Issue tracker URL: `https://github.com/itsallcode/openfasttrace-intellij-plugin/issues` +* Vendor: `itsallcode.org` + +The Marketplace description is maintained in [description.html](description.html). The Marketplace change notes are rendered from the active Markdown release notes under [../changes](../changes/changelog.md) with Pandoc during the Gradle descriptor patching step. Keep Pandoc available on `PATH` in local release environments and CI packaging jobs, or set `PANDOC` to the executable path. diff --git a/doc/system_requirements.md b/doc/system_requirements.md index bac51ca..dc8fbfd 100644 --- a/doc/system_requirements.md +++ b/doc/system_requirements.md @@ -520,6 +520,17 @@ JetBrains plugin surfaces use packaged plugin logo resources to distinguish plug Needs: scn +### Marketplace Metadata for JetBrains Plugin Surfaces +`req~marketplace-metadata-for-jetbrains-plugin-surfaces~1` + +The plugin distribution includes Marketplace-facing descriptor metadata that IntelliJ Platform IDEs and JetBrains Marketplace can display for the plugin. Developers and other OpenFastTrace users can understand the plugin purpose, maintained project links, vendor identity, compatible IDE baseline, and current release notes before installing or updating the plugin. + +Rationale: + +JetBrains plugin surfaces extract key listing information from the packaged plugin descriptor. Clear and maintained metadata helps users judge whether the plugin fits their OpenFastTrace workflow without changing plugin runtime behavior. + +Needs: scn + ### Run Configuration Presentation The following requirements refine how OpenFastTrace run configurations appear in the IDE run/debug UI. @@ -1438,6 +1449,18 @@ Covers: Needs: dsn +### Show Marketplace Metadata in JetBrains Plugin Surfaces +`scn~show-marketplace-metadata-in-jetbrains-plugin-surfaces~1` + +**Given** a maintainer builds the OpenFastTrace plugin distribution with the project Gradle build +**When** an IntelliJ Platform IDE displays the built plugin in `Settings | Plugins`, or JetBrains Marketplace displays the plugin after publication +**Then** the surface can display maintained Marketplace-facing plugin metadata from the packaged plugin descriptor + +Covers: +- `req~marketplace-metadata-for-jetbrains-plugin-surfaces~1` + +Needs: dsn + ### Show OpenFastTrace Icon for Run Configurations `scn~show-openfasttrace-icon-for-run-configurations~1` diff --git a/gradle.properties b/gradle.properties index c9bd9c6..eac6a12 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,4 +1,4 @@ -version=0.8.0 +version=0.8.1 org.gradle.configuration-cache=true org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 diff --git a/src/main/resources/META-INF/plugin.xml b/src/main/resources/META-INF/plugin.xml index 6564fd3..eb52404 100644 --- a/src/main/resources/META-INF/plugin.xml +++ b/src/main/resources/META-INF/plugin.xml @@ -1,10 +1,6 @@ - + com.intellij.modules.platform - - diff --git a/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java new file mode 100644 index 0000000..5d119b1 --- /dev/null +++ b/src/test/java/org/itsallcode/openfasttrace/intellijplugin/OftMarketplaceMetadataTest.java @@ -0,0 +1,92 @@ +package org.itsallcode.openfasttrace.intellijplugin; + +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.w3c.dom.Document; +import org.xml.sax.InputSource; + +import javax.xml.parsers.DocumentBuilderFactory; +import java.io.StringReader; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Properties; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; + +class OftMarketplaceMetadataTest { + private static final String PROJECT_URL = "https://github.com/itsallcode/openfasttrace-intellij-plugin"; + private static final String FIRST_DESCRIPTION_SENTENCE = + "Author requirements directly in your project and trace them all the way down to your implementation " + + "and tests without leaving your IDE."; + + // [itest->dsn~marketplace-plugin-metadata~1] + @Test + void givenMarketplaceDescriptionWhenReadingThenItContainsConfirmedMetadata() throws Exception { + final String description = Files.readString(Path.of("doc/marketplace/description.html")); + + Assertions.assertAll( + () -> assertThat(description, containsString(FIRST_DESCRIPTION_SENTENCE)), + () -> assertThat(description, containsString("developers")), + () -> assertThat(description, containsString("requirement engineers")), + () -> assertThat(description, containsString("quality engineers")), + () -> assertThat(description, containsString("technical writers")), + () -> assertThat(description, containsString("broken requirement chains")) + ); + } + + // [itest->dsn~marketplace-plugin-metadata~1] + @Test + void givenActiveReleaseNotesWhenReadingThenItContainsMarketplaceMetadataEntry() throws Exception { + final String version = projectVersion(); + final String bundledOpenFastTraceVersion = bundledOpenFastTraceVersion(); + final String releaseNotes = Files.readString(Path.of("doc/changes/changes_" + version + ".md")); + + Assertions.assertAll( + () -> assertThat(releaseNotes, containsString("# OpenFastTrace IntelliJ Plugin " + version)), + () -> assertThat(releaseNotes, containsString("#51: Complete Marketplace-facing plugin metadata")), + () -> assertThat(releaseNotes, containsString("clearer overview")), + () -> assertThat(releaseNotes, containsString("installing or updating")), + () -> assertThat(releaseNotes, containsString("## Bundled OpenFastTrace")), + () -> assertThat(releaseNotes, containsString("OpenFastTrace " + bundledOpenFastTraceVersion)) + ); + } + + // [itest->dsn~marketplace-plugin-metadata~1] + @Test + void givenSourcePluginDescriptorWhenReadingThenItContainsProjectWebsiteUrl() throws Exception { + final Document document = loadXml(Files.readString(Path.of("src/main/resources/META-INF/plugin.xml"))); + + assertThat(document.getDocumentElement().getAttribute("url"), is(PROJECT_URL)); + } + + private static String projectVersion() throws Exception { + final Properties properties = new Properties(); + try (var input = Files.newInputStream(Path.of("gradle.properties"))) { + properties.load(input); + } + return properties.getProperty("version"); + } + + private static String bundledOpenFastTraceVersion() throws Exception { + final String prefix = "org.itsallcode.openfasttrace:openfasttrace:"; + try (var lines = Files.lines(Path.of("gradle.lockfile"))) { + return lines + .filter(line -> line.startsWith(prefix)) + .findFirst() + .map(line -> line.substring(prefix.length(), line.indexOf('='))) + .orElseThrow(); + } + } + + private static Document loadXml(final String xml) throws Exception { + final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true); + factory.setFeature("http://xml.org/sax/features/external-general-entities", false); + factory.setFeature("http://xml.org/sax/features/external-parameter-entities", false); + factory.setNamespaceAware(true); + factory.setExpandEntityReferences(false); + return factory.newDocumentBuilder().parse(new InputSource(new StringReader(xml))); + } +} From 7d053ceb624ba47ef29b9fcd283cebd77c50b897 Mon Sep 17 00:00:00 2001 From: redcatbear Date: Wed, 10 Jun 2026 10:34:53 +0200 Subject: [PATCH 2/2] #51: Added a screenshot of the plugin to the readme. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0f66e05..a87cec8 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,8 @@ ## What is OpenFastTrace IntelliJ Plugin? The OpenFastTrace IntelliJ Plugin adds editor and navigation support for OpenFastTrace (OFT) artifacts directly in JetBrains IDEs based on the IntelliJ Platform. +![IDE Window With the Plugin](doc/images/intellij-window-with-plugin.png) + It helps users work with OFT specification items and trace links in the same environment where they already edit code and documentation. ![OFT Logo](doc/images/openfasttrace_logo.svg)