#
tokens: 13277/50000 25/25 files
lines: on (toggle) GitHub
raw markdown copy reset
# Directory Structure

```
├── .github
│   ├── dependabot.yml
│   ├── readme
│   │   └── demo.gif
│   └── workflows
│       ├── build.yml
│       ├── release.yml
│       └── run-ui-tests.yml
├── .gitignore
├── .idea
│   └── gradle.xml
├── .run
│   ├── Run Plugin.run.xml
│   ├── Run Tests.run.xml
│   └── Run Verifications.run.xml
├── build.gradle.kts
├── CHANGELOG.md
├── gradle
│   ├── libs.versions.toml
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── qodana.yml
├── README.md
├── settings.gradle.kts
└── src
    ├── main
    │   ├── kotlin
    │   │   └── com
    │   │       └── github
    │   │           └── gschrader
    │   │               └── openinrunconfig
    │   │                   ├── actions
    │   │                   │   └── RunWithFilePathAction.kt
    │   │                   └── MyBundle.kt
    │   └── resources
    │       ├── messages
    │       │   └── MyBundle.properties
    │       └── META-INF
    │           └── plugin.xml
    └── test
        ├── kotlin
        │   └── com
        │       └── github
        │           └── gschrader
        │               └── openinrunconfig
        │                   └── MyPluginTest.kt
        └── testData
            └── rename
                ├── foo_after.xml
                └── foo.xml
```

# Files

--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------

```
1 | .gradle
2 | .idea
3 | .intellijPlatform
4 | .qodana
5 | build
6 | 
```

--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------

```markdown
 1 | # open-in-run-config-idea-plugin
 2 | 
 3 | ![Build](https://github.com/gschrader/open-in-run-config-idea-plugin/workflows/Build/badge.svg)
 4 | [![Version](https://img.shields.io/jetbrains/plugin/v/27881.svg)](https://plugins.jetbrains.com/plugin/27881)
 5 | [![Downloads](https://img.shields.io/jetbrains/plugin/d/27881.svg)](https://plugins.jetbrains.com/plugin/27881)
 6 | 
 7 | ## Plugin Overview
 8 | 
 9 | <!-- Plugin description -->
10 | The **Open in Run Config** plugin allows you to quickly run any Java application configuration with a selected file as a program argument. It's essentially a productivity tool that eliminates the need to manually edit run configurations when you want to pass a file path to your application.
11 | <!-- Plugin description end -->
12 | 
13 | ![demo](./.github/readme/demo.gif)
14 | 
15 | ## What It Does
16 | 
17 | 1. **Context Menu Integration**: Adds a "Project Application" action to the context menu when you right-click on a file in the Project view or other file browsers in IntelliJ IDEA.
18 | 
19 | 2. **Configuration Selection**: When triggered, it shows a popup list of all available Java Application run configurations in your project.
20 | 
21 | 3. **Automatic File Path Injection**: Once you select a run configuration, it:
22 |   - Creates a temporary copy of the selected configuration
23 |   - Automatically adds the selected file's path as a program argument
24 |   - Runs the configuration immediately
25 | 
26 | 4. **Smart Handling**:
27 |   - Only works with Java Application configurations (not other types like JUnit, etc.)
28 |   - Preserves all original configuration settings (working directory, environment variables, etc.)
29 |   - Creates temporary configurations that don't clutter your permanent run configurations
30 |   - Handles both cases where the configuration already has program arguments and where it doesn't
31 | 
32 | ## Use Cases
33 | 
34 | This plugin is particularly useful when you have applications that:
35 | - Process files (like parsers, converters, analyzers)
36 | - Need file paths as command-line arguments
37 | - Are frequently run with different input files
38 | 
39 | Instead of manually editing run configurations each time, you can simply right-click on any file and run your application with that file as input.
40 | 
```

--------------------------------------------------------------------------------
/src/test/testData/rename/foo_after.xml:
--------------------------------------------------------------------------------

```
1 | <root>
2 |     <a2>Foo</a2>
3 | </root>
4 | 
```

--------------------------------------------------------------------------------
/src/test/testData/rename/foo.xml:
--------------------------------------------------------------------------------

```
1 | <root>
2 |     <a<caret>1>Foo</a1>
3 | </root>
4 | 
```

--------------------------------------------------------------------------------
/settings.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
1 | plugins {
2 |     id("org.gradle.toolchains.foojay-resolver-convention") version "0.8.0"
3 | }
4 | 
5 | rootProject.name = "open-in-run-config-idea-plugin"
6 | 
```

--------------------------------------------------------------------------------
/qodana.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # Qodana configuration:
 2 | # https://www.jetbrains.com/help/qodana/qodana-yaml.html
 3 | 
 4 | version: "1.0"
 5 | linter: jetbrains/qodana-jvm-community:2024.3
 6 | projectJDK: "21"
 7 | profile:
 8 |   name: qodana.recommended
 9 | exclude:
10 |   - name: All
11 |     paths:
12 |       - .qodana
13 | 
```

--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------

```
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
4 | networkTimeout=10000
5 | validateDistributionUrl=true
6 | zipStoreBase=GRADLE_USER_HOME
7 | zipStorePath=wrapper/dists
8 | 
```

--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------

```markdown
1 | <!-- Keep a Changelog guide -> https://keepachangelog.com -->
2 | 
3 | # open-in-run-config-idea-plugin Changelog
4 | 
5 | ## [Unreleased]
6 | ### Added
7 | - Initial scaffold created from [IntelliJ Platform Plugin Template](https://github.com/JetBrains/intellij-platform-plugin-template)
8 | 
```

--------------------------------------------------------------------------------
/src/test/kotlin/com/github/gschrader/openinrunconfig/MyPluginTest.kt:
--------------------------------------------------------------------------------

```kotlin
 1 | package com.github.gschrader.openinrunconfig
 2 | 
 3 | import com.intellij.testFramework.TestDataPath
 4 | import com.intellij.testFramework.fixtures.BasePlatformTestCase
 5 | 
 6 | @TestDataPath("\$CONTENT_ROOT/src/test/testData")
 7 | class MyPluginTest : BasePlatformTestCase() {
 8 |     fun testt() {
 9 |     }
10 | }
11 | 
```

--------------------------------------------------------------------------------
/src/main/resources/messages/MyBundle.properties:
--------------------------------------------------------------------------------

```
1 | runWithFilePath=Project Application
2 | selectConfiguration=Select Configuration to Run
3 | noConfigurationsAvailable=No run configurations are available in this project.
4 | configurationNotSupported=Configuration ''{0}'' does not support program parameters.
5 | executionError=Error executing configuration: {0}
6 | 
```

--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # Dependabot configuration:
 2 | # https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/configuration-options-for-dependency-updates
 3 | 
 4 | version: 2
 5 | updates:
 6 |   # Maintain dependencies for Gradle dependencies
 7 |   - package-ecosystem: "gradle"
 8 |     directory: "/"
 9 |     schedule:
10 |       interval: "daily"
11 |   # Maintain dependencies for GitHub Actions
12 |   - package-ecosystem: "github-actions"
13 |     directory: "/"
14 |     schedule:
15 |       interval: "daily"
16 | 
```

--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------

```
 1 | <?xml version="1.0" encoding="UTF-8"?>
 2 | <project version="4">
 3 |   <component name="GradleMigrationSettings" migrationVersion="1" />
 4 |   <component name="GradleSettings">
 5 |     <option name="linkedExternalProjectsSettings">
 6 |       <GradleProjectSettings>
 7 |         <option name="externalProjectPath" value="$PROJECT_DIR$" />
 8 |         <option name="modules">
 9 |           <set>
10 |             <option value="$PROJECT_DIR$" />
11 |           </set>
12 |         </option>
13 |       </GradleProjectSettings>
14 |     </option>
15 |   </component>
16 | </project>
```

--------------------------------------------------------------------------------
/src/main/kotlin/com/github/gschrader/openinrunconfig/MyBundle.kt:
--------------------------------------------------------------------------------

```kotlin
 1 | package com.github.gschrader.openinrunconfig
 2 | 
 3 | import com.intellij.DynamicBundle
 4 | import org.jetbrains.annotations.NonNls
 5 | import org.jetbrains.annotations.PropertyKey
 6 | 
 7 | @NonNls
 8 | private const val BUNDLE = "messages.MyBundle"
 9 | 
10 | object MyBundle : DynamicBundle(BUNDLE) {
11 | 
12 |     @JvmStatic
13 |     fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
14 |         getMessage(key, *params)
15 | 
16 |     @Suppress("unused")
17 |     @JvmStatic
18 |     fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
19 |         getLazyMessage(key, *params)
20 | }
21 | 
```

--------------------------------------------------------------------------------
/gradle/libs.versions.toml:
--------------------------------------------------------------------------------

```toml
 1 | [versions]
 2 | # libraries
 3 | junit = "4.13.2"
 4 | opentest4j = "1.3.0"
 5 | 
 6 | # plugins
 7 | changelog = "2.2.1"
 8 | intelliJPlatform = "2.5.0"
 9 | kotlin = "2.1.20"
10 | kover = "0.9.1"
11 | qodana = "2024.3.4"
12 | 
13 | [libraries]
14 | junit = { group = "junit", name = "junit", version.ref = "junit" }
15 | opentest4j = { group = "org.opentest4j", name = "opentest4j", version.ref = "opentest4j" }
16 | 
17 | [plugins]
18 | changelog = { id = "org.jetbrains.changelog", version.ref = "changelog" }
19 | intelliJPlatform = { id = "org.jetbrains.intellij.platform", version.ref = "intelliJPlatform" }
20 | kotlin = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
21 | kover = { id = "org.jetbrains.kotlinx.kover", version.ref = "kover" }
22 | qodana = { id = "org.jetbrains.qodana", version.ref = "qodana" }
23 | 
```

--------------------------------------------------------------------------------
/.run/Run Tests.run.xml:
--------------------------------------------------------------------------------

```
 1 | <component name="ProjectRunConfigurationManager">
 2 |   <configuration default="false" name="Run Tests" type="GradleRunConfiguration" factoryName="Gradle">
 3 |     <log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
 4 |     <ExternalSystemSettings>
 5 |       <option name="executionName" />
 6 |       <option name="externalProjectPath" value="$PROJECT_DIR$" />
 7 |       <option name="externalSystemIdString" value="GRADLE" />
 8 |       <option name="scriptParameters" value="" />
 9 |       <option name="taskDescriptions">
10 |         <list />
11 |       </option>
12 |       <option name="taskNames">
13 |         <list>
14 |           <option value="check" />
15 |         </list>
16 |       </option>
17 |       <option name="vmOptions" value="" />
18 |     </ExternalSystemSettings>
19 |     <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
20 |     <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
21 |     <DebugAllEnabled>false</DebugAllEnabled>
22 |     <RunAsTest>true</RunAsTest>
23 |     <method v="2" />
24 |   </configuration>
25 | </component>
26 | 
```

--------------------------------------------------------------------------------
/.run/Run Plugin.run.xml:
--------------------------------------------------------------------------------

```
 1 | <component name="ProjectRunConfigurationManager">
 2 |   <configuration default="false" name="Run Plugin" type="GradleRunConfiguration" factoryName="Gradle">
 3 |     <log_file alias="IDE logs" path="$PROJECT_DIR$/build/idea-sandbox/*/log/idea.log" show_all="true" />
 4 |     <ExternalSystemSettings>
 5 |       <option name="executionName" />
 6 |       <option name="externalProjectPath" value="$PROJECT_DIR$" />
 7 |       <option name="externalSystemIdString" value="GRADLE" />
 8 |       <option name="scriptParameters" value="" />
 9 |       <option name="taskDescriptions">
10 |         <list />
11 |       </option>
12 |       <option name="taskNames">
13 |         <list>
14 |           <option value="runIde" />
15 |         </list>
16 |       </option>
17 |       <option name="vmOptions" value="" />
18 |     </ExternalSystemSettings>
19 |     <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
20 |     <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
21 |     <DebugAllEnabled>false</DebugAllEnabled>
22 |     <RunAsTest>false</RunAsTest>
23 |     <method v="2" />
24 |   </configuration>
25 | </component>
26 | 
```

--------------------------------------------------------------------------------
/.run/Run Verifications.run.xml:
--------------------------------------------------------------------------------

```
 1 | <component name="ProjectRunConfigurationManager">
 2 |   <configuration default="false" name="Run Verifications" type="GradleRunConfiguration" factoryName="Gradle">
 3 |     <log_file alias="idea.log" path="$PROJECT_DIR$/build/idea-sandbox/system/log/idea.log" />
 4 |     <ExternalSystemSettings>
 5 |       <option name="executionName" />
 6 |       <option name="externalProjectPath" value="$PROJECT_DIR$" />
 7 |       <option name="externalSystemIdString" value="GRADLE" />
 8 |       <option name="scriptParameters" value="" />
 9 |       <option name="taskDescriptions">
10 |         <list />
11 |       </option>
12 |       <option name="taskNames">
13 |         <list>
14 |           <option value="verifyPlugin" />
15 |         </list>
16 |       </option>
17 |       <option name="vmOptions" value="" />
18 |     </ExternalSystemSettings>
19 |     <ExternalSystemDebugServerProcess>true</ExternalSystemDebugServerProcess>
20 |     <ExternalSystemReattachDebugProcess>true</ExternalSystemReattachDebugProcess>
21 |     <DebugAllEnabled>false</DebugAllEnabled>
22 |     <RunAsTest>false</RunAsTest>
23 |     <method v="2" />
24 |   </configuration>
25 | </component>
```

--------------------------------------------------------------------------------
/src/main/resources/META-INF/plugin.xml:
--------------------------------------------------------------------------------

```
 1 | <!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
 2 | <idea-plugin>
 3 |     <id>com.github.gschrader.openinrunconfig</id>
 4 |     <name>Open in Run Config</name>
 5 |     <vendor>gschrader</vendor>
 6 |     <description><![CDATA[
 7 | The <b>Open in Run Config</b> plugin allows you to quickly run any Java application configuration with a selected file as a program argument. It's essentially a productivity tool that eliminates the need to manually edit run configurations when you want to pass a file path to your application.
 8 | ]]></description>
 9 | 
10 |     <depends>com.intellij.modules.platform</depends>
11 |     <depends>com.intellij.modules.java</depends>
12 | 
13 |     <resource-bundle>messages.MyBundle</resource-bundle>
14 | 
15 |     <actions>
16 |         <action id="RunWithFilePathAction" 
17 |                 class="com.github.gschrader.openinrunconfig.actions.RunWithFilePathAction"
18 |                 text="Project Application"
19 |                 description="Run with the selected file path as program argument">
20 |             
21 |             <add-to-group group-id="UsageView.Popup" anchor="last"/>
22 |             <add-to-group group-id="RevealGroup" anchor="last"/>
23 |         </action>
24 |     </actions>
25 | </idea-plugin>
26 | 
```

--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------

```
 1 | # IntelliJ Platform Artifacts Repositories -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html
 2 | 
 3 | pluginGroup = com.github.gschrader.openinrunconfig
 4 | pluginName = open-in-run-config
 5 | pluginRepositoryUrl = https://github.com/gschrader/open-in-run-config-idea-plugin
 6 | # SemVer format -> https://semver.org
 7 | pluginVersion = 0.0.4
 8 | 
 9 | # Supported build number ranges and IntelliJ Platform versions -> https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
10 | pluginSinceBuild = 242
11 | pluginUntilBuild = 252.*
12 | 
13 | # IntelliJ Platform Properties -> https://plugins.jetbrains.com/docs/intellij/tools-gradle-intellij-plugin.html#configuration-intellij-extension
14 | platformType = IC
15 | platformVersion = 2024.2.5
16 | 
17 | # Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
18 | # Example: platformPlugins = com.jetbrains.php:203.4449.22, org.intellij.scala:2023.3.27@EAP
19 | platformPlugins =
20 | # Example: platformBundledPlugins = com.intellij.java
21 | platformBundledPlugins = com.intellij.java, org.jetbrains.kotlin
22 | 
23 | # Gradle Releases -> https://github.com/gradle/gradle/releases
24 | gradleVersion = 8.13
25 | 
26 | # Opt-out flag for bundling Kotlin standard library -> https://jb.gg/intellij-platform-kotlin-stdlib
27 | kotlin.stdlib.default.dependency = false
28 | 
29 | # Enable Gradle Configuration Cache -> https://docs.gradle.org/current/userguide/configuration_cache.html
30 | org.gradle.configuration-cache = true
31 | 
32 | # Enable Gradle Build Cache -> https://docs.gradle.org/current/userguide/build_cache.html
33 | org.gradle.caching = true
34 | 
```

--------------------------------------------------------------------------------
/.github/workflows/run-ui-tests.yml:
--------------------------------------------------------------------------------

```yaml
 1 | # GitHub Actions Workflow for launching UI tests on Linux, Windows, and Mac in the following steps:
 2 | # - Prepare and launch IDE with your plugin and robot-server plugin, which is needed to interact with the UI.
 3 | # - Wait for IDE to start.
 4 | # - Run UI tests with a separate Gradle task.
 5 | #
 6 | # Please check https://github.com/JetBrains/intellij-ui-test-robot for information about UI tests with IntelliJ Platform.
 7 | #
 8 | # Workflow is triggered manually.
 9 | 
10 | name: Run UI Tests
11 | on:
12 |   workflow_dispatch
13 | 
14 | jobs:
15 | 
16 |   testUI:
17 |     runs-on: ${{ matrix.os }}
18 |     strategy:
19 |       fail-fast: false
20 |       matrix:
21 |         include:
22 |           - os: ubuntu-latest
23 |             runIde: |
24 |               export DISPLAY=:99.0
25 |               Xvfb -ac :99 -screen 0 1920x1080x16 &
26 |               gradle runIdeForUiTests &
27 |           - os: windows-latest
28 |             runIde: start gradlew.bat runIdeForUiTests
29 |           - os: macos-latest
30 |             runIde: ./gradlew runIdeForUiTests &
31 | 
32 |     steps:
33 | 
34 |       # Check out the current repository
35 |       - name: Fetch Sources
36 |         uses: actions/checkout@v4
37 | 
38 |       # Set up Java environment for the next steps
39 |       - name: Setup Java
40 |         uses: actions/setup-java@v4
41 |         with:
42 |           distribution: zulu
43 |           java-version: 21
44 | 
45 |       # Setup Gradle
46 |       - name: Setup Gradle
47 |         uses: gradle/actions/setup-gradle@v4
48 | 
49 |       # Run IDEA prepared for UI testing
50 |       - name: Run IDE
51 |         run: ${{ matrix.runIde }}
52 | 
53 |       # Wait for IDEA to be started
54 |       - name: Health Check
55 |         uses: jtalk/url-health-check-action@v4
56 |         with:
57 |           url: http://127.0.0.1:8082
58 |           max-attempts: 15
59 |           retry-delay: 30s
60 | 
61 |       # Run tests
62 |       - name: Tests
63 |         run: ./gradlew test
64 | 
```

--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------

```
 1 | @rem
 2 | @rem Copyright 2015 the original author or authors.
 3 | @rem
 4 | @rem Licensed under the Apache License, Version 2.0 (the "License");
 5 | @rem you may not use this file except in compliance with the License.
 6 | @rem You may obtain a copy of the License at
 7 | @rem
 8 | @rem      https://www.apache.org/licenses/LICENSE-2.0
 9 | @rem
10 | @rem Unless required by applicable law or agreed to in writing, software
11 | @rem distributed under the License is distributed on an "AS IS" BASIS,
12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | @rem See the License for the specific language governing permissions and
14 | @rem limitations under the License.
15 | @rem
16 | @rem SPDX-License-Identifier: Apache-2.0
17 | @rem
18 | 
19 | @if "%DEBUG%"=="" @echo off
20 | @rem ##########################################################################
21 | @rem
22 | @rem  Gradle startup script for Windows
23 | @rem
24 | @rem ##########################################################################
25 | 
26 | @rem Set local scope for the variables with windows NT shell
27 | if "%OS%"=="Windows_NT" setlocal
28 | 
29 | set DIRNAME=%~dp0
30 | if "%DIRNAME%"=="" set DIRNAME=.
31 | @rem This is normally unused
32 | set APP_BASE_NAME=%~n0
33 | set APP_HOME=%DIRNAME%
34 | 
35 | @rem Resolve any "." and ".." in APP_HOME to make it shorter.
36 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
37 | 
38 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
39 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
40 | 
41 | @rem Find java.exe
42 | if defined JAVA_HOME goto findJavaFromJavaHome
43 | 
44 | set JAVA_EXE=java.exe
45 | %JAVA_EXE% -version >NUL 2>&1
46 | if %ERRORLEVEL% equ 0 goto execute
47 | 
48 | echo. 1>&2
49 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
50 | echo. 1>&2
51 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
52 | echo location of your Java installation. 1>&2
53 | 
54 | goto fail
55 | 
56 | :findJavaFromJavaHome
57 | set JAVA_HOME=%JAVA_HOME:"=%
58 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
59 | 
60 | if exist "%JAVA_EXE%" goto execute
61 | 
62 | echo. 1>&2
63 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
64 | echo. 1>&2
65 | echo Please set the JAVA_HOME variable in your environment to match the 1>&2
66 | echo location of your Java installation. 1>&2
67 | 
68 | goto fail
69 | 
70 | :execute
71 | @rem Setup the command line
72 | 
73 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
74 | 
75 | 
76 | @rem Execute Gradle
77 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
78 | 
79 | :end
80 | @rem End local scope for the variables with windows NT shell
81 | if %ERRORLEVEL% equ 0 goto mainEnd
82 | 
83 | :fail
84 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
85 | rem the _cmd.exe /c_ return code!
86 | set EXIT_CODE=%ERRORLEVEL%
87 | if %EXIT_CODE% equ 0 set EXIT_CODE=1
88 | if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
89 | exit /b %EXIT_CODE%
90 | 
91 | :mainEnd
92 | if "%OS%"=="Windows_NT" endlocal
93 | 
94 | :omega
95 | 
```

--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------

```yaml
  1 | # GitHub Actions Workflow created for handling the release process based on the draft release prepared with the Build workflow.
  2 | # Running the publishPlugin task requires all following secrets to be provided: PUBLISH_TOKEN, PRIVATE_KEY, PRIVATE_KEY_PASSWORD, CERTIFICATE_CHAIN.
  3 | # See https://plugins.jetbrains.com/docs/intellij/plugin-signing.html for more information.
  4 | 
  5 | name: Release
  6 | on:
  7 |   release:
  8 |     types: [prereleased, released]
  9 | 
 10 | jobs:
 11 | 
 12 |   # Prepare and publish the plugin to JetBrains Marketplace repository
 13 |   release:
 14 |     name: Publish Plugin
 15 |     runs-on: ubuntu-latest
 16 |     permissions:
 17 |       contents: write
 18 |       pull-requests: write
 19 |     steps:
 20 | 
 21 |       # Free GitHub Actions Environment Disk Space
 22 |       - name: Maximize Build Space
 23 |         # jlumbroso/[email protected]:
 24 |         uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
 25 |         with:
 26 |           tool-cache: false
 27 |           large-packages: false
 28 | 
 29 |       # Check out the current repository
 30 |       - name: Fetch Sources
 31 |         uses: actions/checkout@v4
 32 |         with:
 33 |           ref: ${{ github.event.release.tag_name }}
 34 | 
 35 |       # Set up Java environment for the next steps
 36 |       - name: Setup Java
 37 |         uses: actions/setup-java@v4
 38 |         with:
 39 |           distribution: zulu
 40 |           java-version: 21
 41 | 
 42 |       # Setup Gradle
 43 |       - name: Setup Gradle
 44 |         uses: gradle/actions/setup-gradle@v4
 45 | 
 46 |       # Set environment variables
 47 |       - name: Export Properties
 48 |         id: properties
 49 |         shell: bash
 50 |         run: |
 51 |           CHANGELOG="$(cat << 'EOM' | sed -e 's/^[[:space:]]*$//g' -e '/./,$!d'
 52 |           ${{ github.event.release.body }}
 53 |           EOM
 54 |           )"
 55 |           
 56 |           echo "changelog<<EOF" >> $GITHUB_OUTPUT
 57 |           echo "$CHANGELOG" >> $GITHUB_OUTPUT
 58 |           echo "EOF" >> $GITHUB_OUTPUT
 59 | 
 60 |       # Update the Unreleased section with the current release note
 61 |       - name: Patch Changelog
 62 |         if: ${{ steps.properties.outputs.changelog != '' }}
 63 |         env:
 64 |           CHANGELOG: ${{ steps.properties.outputs.changelog }}
 65 |         run: |
 66 |           ./gradlew patchChangelog --release-note="$CHANGELOG"
 67 | 
 68 |       # Publish the plugin to JetBrains Marketplace
 69 |       - name: Publish Plugin
 70 |         env:
 71 |           PUBLISH_TOKEN: ${{ secrets.PUBLISH_TOKEN }}
 72 |           CERTIFICATE_CHAIN: ${{ secrets.CERTIFICATE_CHAIN }}
 73 |           PRIVATE_KEY: ${{ secrets.PRIVATE_KEY }}
 74 |           PRIVATE_KEY_PASSWORD: ${{ secrets.PRIVATE_KEY_PASSWORD }}
 75 |         run: ./gradlew publishPlugin
 76 | 
 77 |       # Upload artifact as a release asset
 78 |       - name: Upload Release Asset
 79 |         env:
 80 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 81 |         run: gh release upload ${{ github.event.release.tag_name }} ./build/distributions/*
 82 | 
 83 |       # Create a pull request
 84 |       - name: Create Pull Request
 85 |         if: ${{ steps.properties.outputs.changelog != '' }}
 86 |         env:
 87 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 88 |         run: |
 89 |           VERSION="${{ github.event.release.tag_name }}"
 90 |           BRANCH="changelog-update-$VERSION"
 91 |           LABEL="release changelog"
 92 | 
 93 |           git config user.email "[email protected]"
 94 |           git config user.name "GitHub Action"
 95 | 
 96 |           git checkout -b $BRANCH
 97 |           git commit -am "Changelog update - $VERSION"
 98 |           git push --set-upstream origin $BRANCH
 99 |           
100 |           gh label create "$LABEL" \
101 |             --description "Pull requests with release changelog update" \
102 |             --force \
103 |             || true
104 | 
105 |           gh pr create \
106 |             --title "Changelog update - \`$VERSION\`" \
107 |             --body "Current pull request contains patched \`CHANGELOG.md\` file for the \`$VERSION\` version." \
108 |             --label "$LABEL" \
109 |             --head $BRANCH
110 | 
```

--------------------------------------------------------------------------------
/build.gradle.kts:
--------------------------------------------------------------------------------

```kotlin
  1 | import org.jetbrains.changelog.Changelog
  2 | import org.jetbrains.changelog.markdownToHTML
  3 | import org.jetbrains.intellij.platform.gradle.TestFrameworkType
  4 | 
  5 | plugins {
  6 |     id("java") // Java support
  7 |     alias(libs.plugins.kotlin) // Kotlin support
  8 |     alias(libs.plugins.intelliJPlatform) // IntelliJ Platform Gradle Plugin
  9 |     alias(libs.plugins.changelog) // Gradle Changelog Plugin
 10 |     alias(libs.plugins.qodana) // Gradle Qodana Plugin
 11 |     alias(libs.plugins.kover) // Gradle Kover Plugin
 12 | }
 13 | 
 14 | group = providers.gradleProperty("pluginGroup").get()
 15 | version = providers.gradleProperty("pluginVersion").get()
 16 | 
 17 | // Set the JVM language level used to build the project.
 18 | kotlin {
 19 |     jvmToolchain(21)
 20 | }
 21 | 
 22 | // Configure project's dependencies
 23 | repositories {
 24 |     mavenCentral()
 25 | 
 26 |     // IntelliJ Platform Gradle Plugin Repositories Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-repositories-extension.html
 27 |     intellijPlatform {
 28 |         defaultRepositories()
 29 |     }
 30 | }
 31 | 
 32 | // Dependencies are managed with Gradle version catalog - read more: https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog
 33 | dependencies {
 34 |     testImplementation(libs.junit)
 35 |     testImplementation(libs.opentest4j)
 36 | 
 37 |     // IntelliJ Platform Gradle Plugin Dependencies Extension - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-dependencies-extension.html
 38 |     intellijPlatform {
 39 |         create(providers.gradleProperty("platformType"), providers.gradleProperty("platformVersion"))
 40 | 
 41 |         // Plugin Dependencies. Uses `platformBundledPlugins` property from the gradle.properties file for bundled IntelliJ Platform plugins.
 42 |         bundledPlugins(providers.gradleProperty("platformBundledPlugins").map { it.split(',') })
 43 | 
 44 |         // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file for plugin from JetBrains Marketplace.
 45 |         plugins(providers.gradleProperty("platformPlugins").map { it.split(',') })
 46 | 
 47 |         testFramework(TestFrameworkType.Platform)
 48 |     }
 49 | }
 50 | 
 51 | // Configure IntelliJ Platform Gradle Plugin - read more: https://plugins.jetbrains.com/docs/intellij/tools-intellij-platform-gradle-plugin-extension.html
 52 | intellijPlatform {
 53 |     pluginConfiguration {
 54 |         name = providers.gradleProperty("pluginName")
 55 |         version = providers.gradleProperty("pluginVersion")
 56 | 
 57 |         // Extract the <!-- Plugin description --> section from README.md and provide for the plugin's manifest
 58 |         description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map {
 59 |             val start = "<!-- Plugin description -->"
 60 |             val end = "<!-- Plugin description end -->"
 61 | 
 62 |             with(it.lines()) {
 63 |                 if (!containsAll(listOf(start, end))) {
 64 |                     throw GradleException("Plugin description section not found in README.md:\n$start ... $end")
 65 |                 }
 66 |                 subList(indexOf(start) + 1, indexOf(end)).joinToString("\n").let(::markdownToHTML)
 67 |             }
 68 |         }
 69 | 
 70 |         val changelog = project.changelog // local variable for configuration cache compatibility
 71 |         // Get the latest available change notes from the changelog file
 72 |         changeNotes = providers.gradleProperty("pluginVersion").map { pluginVersion ->
 73 |             with(changelog) {
 74 |                 renderItem(
 75 |                     (getOrNull(pluginVersion) ?: getUnreleased())
 76 |                         .withHeader(false)
 77 |                         .withEmptySections(false),
 78 |                     Changelog.OutputType.HTML,
 79 |                 )
 80 |             }
 81 |         }
 82 | 
 83 |         ideaVersion {
 84 |             sinceBuild = providers.gradleProperty("pluginSinceBuild")
 85 |             untilBuild = providers.gradleProperty("pluginUntilBuild")
 86 |         }
 87 |     }
 88 | 
 89 |     signing {
 90 |         certificateChain = providers.environmentVariable("CERTIFICATE_CHAIN")
 91 |         privateKey = providers.environmentVariable("PRIVATE_KEY")
 92 |         password = providers.environmentVariable("PRIVATE_KEY_PASSWORD")
 93 |     }
 94 | 
 95 |     publishing {
 96 |         token = providers.environmentVariable("PUBLISH_TOKEN")
 97 |         // The pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
 98 |         // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
 99 |         // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
100 |         channels = providers.gradleProperty("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) }
101 |     }
102 | 
103 |     pluginVerification {
104 |         ides {
105 |             recommended()
106 |         }
107 |     }
108 | }
109 | 
110 | // Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
111 | changelog {
112 |     groups.empty()
113 |     repositoryUrl = providers.gradleProperty("pluginRepositoryUrl")
114 | }
115 | 
116 | // Configure Gradle Kover Plugin - read more: https://github.com/Kotlin/kotlinx-kover#configuration
117 | kover {
118 |     reports {
119 |         total {
120 |             xml {
121 |                 onCheck = true
122 |             }
123 |         }
124 |     }
125 | }
126 | 
127 | tasks {
128 |     wrapper {
129 |         gradleVersion = providers.gradleProperty("gradleVersion").get()
130 |     }
131 | 
132 |     publishPlugin {
133 |         dependsOn(patchChangelog)
134 |     }
135 | }
136 | 
137 | intellijPlatformTesting {
138 |     runIde {
139 |         register("runIdeForUiTests") {
140 |             task {
141 |                 jvmArgumentProviders += CommandLineArgumentProvider {
142 |                     listOf(
143 |                         "-Drobot-server.port=8082",
144 |                         "-Dide.mac.message.dialogs.as.sheets=false",
145 |                         "-Djb.privacy.policy.text=<!--999.999-->",
146 |                         "-Djb.consents.confirmation.enabled=false",
147 |                     )
148 |                 }
149 |             }
150 | 
151 |             plugins {
152 |                 robotServerPlugin()
153 |             }
154 |         }
155 |     }
156 | }
157 | 
```

--------------------------------------------------------------------------------
/src/main/kotlin/com/github/gschrader/openinrunconfig/actions/RunWithFilePathAction.kt:
--------------------------------------------------------------------------------

```kotlin
  1 | package com.github.gschrader.openinrunconfig.actions
  2 | 
  3 | import com.github.gschrader.openinrunconfig.MyBundle
  4 | import com.intellij.execution.CommonProgramRunConfigurationParameters
  5 | import com.intellij.execution.ProgramRunnerUtil
  6 | import com.intellij.execution.RunManager
  7 | import com.intellij.execution.application.ApplicationConfiguration
  8 | import com.intellij.execution.configurations.RunConfiguration
  9 | import com.intellij.execution.executors.DefaultRunExecutor
 10 | import com.intellij.openapi.actionSystem.ActionUpdateThread
 11 | import com.intellij.openapi.actionSystem.AnAction
 12 | import com.intellij.openapi.actionSystem.AnActionEvent
 13 | import com.intellij.openapi.actionSystem.CommonDataKeys
 14 | import com.intellij.openapi.project.Project
 15 | import com.intellij.openapi.ui.Messages
 16 | import com.intellij.openapi.ui.popup.JBPopupFactory
 17 | import com.intellij.openapi.ui.popup.PopupStep
 18 | import com.intellij.openapi.ui.popup.util.BaseListPopupStep
 19 | import com.intellij.openapi.vfs.VirtualFile
 20 | import javax.swing.Icon
 21 | 
 22 | class RunWithFilePathAction : AnAction() {
 23 | 
 24 |     override fun actionPerformed(e: AnActionEvent) {
 25 |         val project = e.project ?: return
 26 |         val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE) ?: return
 27 |         
 28 |         val runManager = RunManager.getInstance(project)
 29 |         val allSettings = runManager.allSettings
 30 |         val configurations = allSettings
 31 |             .filter { (it.configuration.type.id == "Application" || it.configuration.type.id == "JetRunConfigurationType") && !it.isTemporary }
 32 |             .map { it.configuration }
 33 |         
 34 |         if (configurations.isEmpty()) {
 35 |             Messages.showInfoMessage(
 36 |                 project, 
 37 |                 MyBundle.message("noConfigurationsAvailable"),
 38 |                 MyBundle.message("runWithFilePath")
 39 |             )
 40 |             return
 41 |         }
 42 |         
 43 |         val popup = JBPopupFactory.getInstance().createListPopup(
 44 |             ConfigurationListPopupStep(configurations, virtualFile, project)
 45 |         )
 46 |         
 47 |         popup.showInBestPositionFor(e.dataContext)
 48 |     }
 49 |     
 50 |     override fun update(e: AnActionEvent) {
 51 |         val project = e.project
 52 |         val virtualFile = e.getData(CommonDataKeys.VIRTUAL_FILE)
 53 |         
 54 |         // Enable action only if we have a project
 55 |         e.presentation.isEnabledAndVisible = project != null && virtualFile != null
 56 |     }
 57 |     
 58 |     override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT
 59 |     
 60 |     private class ConfigurationListPopupStep(
 61 |         private val configurations: List<RunConfiguration>,
 62 |         private val virtualFile: VirtualFile,
 63 |         private val project: Project
 64 |     ) : BaseListPopupStep<RunConfiguration>(MyBundle.message("selectConfiguration"), configurations) {
 65 |         
 66 |         override fun getTextFor(value: RunConfiguration): String = value.name
 67 |         
 68 |         override fun getIconFor(value: RunConfiguration): Icon? = value.icon
 69 |         
 70 |         override fun onChosen(selectedValue: RunConfiguration, finalChoice: Boolean): PopupStep<*>? {
 71 |             if (finalChoice) {
 72 |                 runConfigurationWithFilePath(selectedValue, virtualFile, project)
 73 |             }
 74 |             return PopupStep.FINAL_CHOICE
 75 |         }
 76 |         
 77 |         private fun runConfigurationWithFilePath(configuration: RunConfiguration, file: VirtualFile, project: Project) {
 78 |             val runManager = RunManager.getInstance(project)
 79 |             
 80 |             try {
 81 |                 // Create a temporary copy of the configuration
 82 |                 val factory = configuration.factory ?: run {
 83 |                     Messages.showErrorDialog(
 84 |                         project,
 85 |                         MyBundle.message("configurationNotSupported", configuration.name),
 86 |                         MyBundle.message("runWithFilePath")
 87 |                     )
 88 |                     return
 89 |                 }
 90 |                 
 91 |                 val tempSettings = runManager.createConfiguration(
 92 |                     "${configuration.name} (with ${file.name})",
 93 |                     factory
 94 |                 )
 95 |                 
 96 |                 val tempConfiguration = tempSettings.configuration
 97 |                 
 98 |                 // Copy settings from original configuration to temporary one
 99 |                 copyConfigurationSettings(configuration, tempConfiguration)
100 |                 
101 |                 // Add the file path as a program argument to the temporary configuration
102 |                 val filePath = file.path
103 |                 val success = addProgramArgument(tempConfiguration, filePath)
104 |                 
105 |                 if (!success) {
106 |                     Messages.showWarningDialog(
107 |                         project,
108 |                         MyBundle.message("configurationNotSupported", configuration.name),
109 |                         MyBundle.message("runWithFilePath")
110 |                     )
111 |                     return
112 |                 }
113 |                 
114 |                 // Set the configuration as temporary
115 |                 tempSettings.isTemporary = true
116 |                 
117 |                 // Add the temporary configuration to the run manager so it persists
118 |                 runManager.addConfiguration(tempSettings)
119 |                 
120 |                 // Set it as the selected configuration
121 |                 runManager.selectedConfiguration = tempSettings
122 |                 
123 |                 // Execute the temporary configuration
124 |                 val executor = DefaultRunExecutor.getRunExecutorInstance()
125 |                 ProgramRunnerUtil.executeConfiguration(tempSettings, executor)
126 |                 
127 |             } catch (e: Exception) {
128 |                 Messages.showErrorDialog(
129 |                     project,
130 |                     MyBundle.message("executionError", e.message ?: "Unknown error"),
131 |                     MyBundle.message("runWithFilePath")
132 |                 )
133 |             }
134 |         }
135 |         
136 |         private fun copyConfigurationSettings(source: RunConfiguration, target: RunConfiguration) {
137 |             if (source is ApplicationConfiguration && target is ApplicationConfiguration) {
138 |                 target.programParameters = source.programParameters
139 |                 target.workingDirectory = source.workingDirectory
140 |                 target.mainClassName = source.mainClassName
141 |                 target.envs = HashMap(source.envs)
142 |                 target.isPassParentEnvs = source.isPassParentEnvs
143 |                 target.configurationModule.module = source.configurationModule.module
144 |             }
145 |         }
146 | 
147 |         private fun addProgramArgument(configuration: RunConfiguration, argument: String): Boolean {
148 |             if (configuration is CommonProgramRunConfigurationParameters) {
149 |                 val currentParams = configuration.programParameters
150 |                 val newParams = if (currentParams.isNullOrEmpty()) {
151 |                     "\"$argument\""
152 |                 } else {
153 |                     "$currentParams \"$argument\""
154 |                 }
155 |                 configuration.programParameters = newParams
156 |                 return true
157 |             }
158 |             return false
159 |         }
160 |     }
161 | } 
```

--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------

```yaml
  1 | # GitHub Actions Workflow is created for testing and preparing the plugin release in the following steps:
  2 | # - Validate Gradle Wrapper.
  3 | # - Run 'test' and 'verifyPlugin' tasks.
  4 | # - Run Qodana inspections.
  5 | # - Run the 'buildPlugin' task and prepare artifact for further tests.
  6 | # - Run the 'runPluginVerifier' task.
  7 | # - Create a draft release.
  8 | #
  9 | # The workflow is triggered on push and pull_request events.
 10 | #
 11 | # GitHub Actions reference: https://help.github.com/en/actions
 12 | #
 13 | ## JBIJPPTPL
 14 | 
 15 | name: Build
 16 | on:
 17 |   # Trigger the workflow on pushes to only the 'main' branch (this avoids duplicate checks being run e.g., for dependabot pull requests)
 18 |   push:
 19 |     branches: [ main ]
 20 |   # Trigger the workflow on any pull request
 21 |   pull_request:
 22 | 
 23 | concurrency:
 24 |   group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
 25 |   cancel-in-progress: true
 26 |   
 27 | jobs:
 28 | 
 29 |   # Prepare environment and build the plugin
 30 |   build:
 31 |     name: Build
 32 |     runs-on: ubuntu-latest
 33 |     outputs:
 34 |       version: ${{ steps.properties.outputs.version }}
 35 |       changelog: ${{ steps.properties.outputs.changelog }}
 36 |       pluginVerifierHomeDir: ${{ steps.properties.outputs.pluginVerifierHomeDir }}
 37 |     steps:
 38 | 
 39 |       # Free GitHub Actions Environment Disk Space
 40 |       - name: Maximize Build Space
 41 |         # jlumbroso/[email protected]:
 42 |         uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
 43 |         with:
 44 |           tool-cache: false
 45 |           large-packages: false
 46 | 
 47 |       # Check out the current repository
 48 |       - name: Fetch Sources
 49 |         uses: actions/checkout@v4
 50 | 
 51 |       # Set up Java environment for the next steps
 52 |       - name: Setup Java
 53 |         uses: actions/setup-java@v4
 54 |         with:
 55 |           distribution: zulu
 56 |           java-version: 21
 57 | 
 58 |       # Setup Gradle
 59 |       - name: Setup Gradle
 60 |         uses: gradle/actions/setup-gradle@v4
 61 | 
 62 |       # Set environment variables
 63 |       - name: Export Properties
 64 |         id: properties
 65 |         shell: bash
 66 |         run: |
 67 |           PROPERTIES="$(./gradlew properties --console=plain -q)"
 68 |           VERSION="$(echo "$PROPERTIES" | grep "^version:" | cut -f2- -d ' ')"
 69 |           CHANGELOG="$(./gradlew getChangelog --unreleased --no-header --console=plain -q)"
 70 | 
 71 |           echo "version=$VERSION" >> $GITHUB_OUTPUT
 72 |           echo "pluginVerifierHomeDir=~/.pluginVerifier" >> $GITHUB_OUTPUT
 73 |           
 74 |           echo "changelog<<EOF" >> $GITHUB_OUTPUT
 75 |           echo "$CHANGELOG" >> $GITHUB_OUTPUT
 76 |           echo "EOF" >> $GITHUB_OUTPUT
 77 | 
 78 |       # Build plugin
 79 |       - name: Build plugin
 80 |         run: ./gradlew buildPlugin
 81 | 
 82 |       # Prepare plugin archive content for creating artifact
 83 |       - name: Prepare Plugin Artifact
 84 |         id: artifact
 85 |         shell: bash
 86 |         run: |
 87 |           cd ${{ github.workspace }}/build/distributions
 88 |           FILENAME=`ls *.zip`
 89 |           unzip "$FILENAME" -d content
 90 | 
 91 |           echo "filename=${FILENAME:0:-4}" >> $GITHUB_OUTPUT
 92 | 
 93 |       # Store already-built plugin as an artifact for downloading
 94 |       - name: Upload artifact
 95 |         uses: actions/upload-artifact@v4
 96 |         with:
 97 |           name: ${{ steps.artifact.outputs.filename }}
 98 |           path: ./build/distributions/content/*/*
 99 | 
100 |   # Run tests and upload a code coverage report
101 |   test:
102 |     name: Test
103 |     needs: [ build ]
104 |     runs-on: ubuntu-latest
105 |     steps:
106 | 
107 |       # Free GitHub Actions Environment Disk Space
108 |       - name: Maximize Build Space
109 |         uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
110 |         with:
111 |           tool-cache: false
112 |           large-packages: false
113 | 
114 |       # Check out the current repository
115 |       - name: Fetch Sources
116 |         uses: actions/checkout@v4
117 | 
118 |       # Set up Java environment for the next steps
119 |       - name: Setup Java
120 |         uses: actions/setup-java@v4
121 |         with:
122 |           distribution: zulu
123 |           java-version: 21
124 | 
125 |       # Setup Gradle
126 |       - name: Setup Gradle
127 |         uses: gradle/actions/setup-gradle@v4
128 | 
129 |       # Run tests
130 |       - name: Run Tests
131 |         run: ./gradlew check
132 | 
133 |       # Collect Tests Result of failed tests
134 |       - name: Collect Tests Result
135 |         if: ${{ failure() }}
136 |         uses: actions/upload-artifact@v4
137 |         with:
138 |           name: tests-result
139 |           path: ${{ github.workspace }}/build/reports/tests
140 | 
141 |       # Upload the Kover report to CodeCov
142 |       - name: Upload Code Coverage Report
143 |         uses: codecov/codecov-action@v5
144 |         with:
145 |           files: ${{ github.workspace }}/build/reports/kover/report.xml
146 | 
147 |   # Run Qodana inspections and provide report
148 |   inspectCode:
149 |     name: Inspect code
150 |     needs: [ build ]
151 |     runs-on: ubuntu-latest
152 |     permissions:
153 |       contents: write
154 |       checks: write
155 |       pull-requests: write
156 |     steps:
157 | 
158 |       # Free GitHub Actions Environment Disk Space
159 |       - name: Maximize Build Space
160 |         uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
161 |         with:
162 |           tool-cache: false
163 |           large-packages: false
164 | 
165 |       # Check out the current repository
166 |       - name: Fetch Sources
167 |         uses: actions/checkout@v4
168 |         with:
169 |           ref: ${{ github.event.pull_request.head.sha }}  # to check out the actual pull request commit, not the merge commit
170 |           fetch-depth: 0  # a full history is required for pull request analysis
171 | 
172 |       # Set up Java environment for the next steps
173 |       - name: Setup Java
174 |         uses: actions/setup-java@v4
175 |         with:
176 |           distribution: zulu
177 |           java-version: 21
178 | 
179 |       # Run Qodana inspections
180 |       - name: Qodana - Code Inspection
181 |         uses: JetBrains/[email protected]
182 |         with:
183 |           cache-default-branch-only: true
184 | 
185 |   # Run plugin structure verification along with IntelliJ Plugin Verifier
186 |   verify:
187 |     name: Verify plugin
188 |     needs: [ build ]
189 |     runs-on: ubuntu-latest
190 |     steps:
191 | 
192 |       # Free GitHub Actions Environment Disk Space
193 |       - name: Maximize Build Space
194 |         uses: jlumbroso/free-disk-space@54081f138730dfa15788a46383842cd2f914a1be
195 |         with:
196 |           tool-cache: false
197 |           large-packages: false
198 | 
199 |       # Check out the current repository
200 |       - name: Fetch Sources
201 |         uses: actions/checkout@v4
202 | 
203 |       # Set up Java environment for the next steps
204 |       - name: Setup Java
205 |         uses: actions/setup-java@v4
206 |         with:
207 |           distribution: zulu
208 |           java-version: 21
209 | 
210 |       # Setup Gradle
211 |       - name: Setup Gradle
212 |         uses: gradle/actions/setup-gradle@v4
213 | 
214 |       # Cache Plugin Verifier IDEs
215 |       - name: Setup Plugin Verifier IDEs Cache
216 |         uses: actions/cache@v4
217 |         with:
218 |           path: ${{ needs.build.outputs.pluginVerifierHomeDir }}/ides
219 |           key: plugin-verifier-${{ hashFiles('build/listProductsReleases.txt') }}
220 | 
221 |       # Run Verify Plugin task and IntelliJ Plugin Verifier tool
222 |       - name: Run Plugin Verification tasks
223 |         run: ./gradlew verifyPlugin -Dplugin.verifier.home.dir=${{ needs.build.outputs.pluginVerifierHomeDir }}
224 | 
225 |       # Collect Plugin Verifier Result
226 |       - name: Collect Plugin Verifier Result
227 |         if: ${{ always() }}
228 |         uses: actions/upload-artifact@v4
229 |         with:
230 |           name: pluginVerifier-result
231 |           path: ${{ github.workspace }}/build/reports/pluginVerifier
232 | 
233 |   # Prepare a draft release for GitHub Releases page for the manual verification
234 |   # If accepted and published, release workflow would be triggered
235 |   releaseDraft:
236 |     name: Release draft
237 |     if: github.event_name != 'pull_request'
238 |     needs: [ build, test, inspectCode, verify ]
239 |     runs-on: ubuntu-latest
240 |     permissions:
241 |       contents: write
242 |     steps:
243 | 
244 |       # Check out the current repository
245 |       - name: Fetch Sources
246 |         uses: actions/checkout@v4
247 | 
248 |       # Remove old release drafts by using the curl request for the available releases with a draft flag
249 |       - name: Remove Old Release Drafts
250 |         env:
251 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
252 |         run: |
253 |           gh api repos/{owner}/{repo}/releases \
254 |             --jq '.[] | select(.draft == true) | .id' \
255 |             | xargs -I '{}' gh api -X DELETE repos/{owner}/{repo}/releases/{}
256 | 
257 |       # Create a new release draft which is not publicly visible and requires manual acceptance
258 |       - name: Create Release Draft
259 |         env:
260 |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
261 |         run: |
262 |           gh release create "v${{ needs.build.outputs.version }}" \
263 |             --draft \
264 |             --title "v${{ needs.build.outputs.version }}" \
265 |             --notes "$(cat << 'EOM'
266 |           ${{ needs.build.outputs.changelog }}
267 |           EOM
268 |           )"
269 | 
```