# 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 |  4 | [](https://plugins.jetbrains.com/plugin/27881) 5 | [](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 |  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 | ```