EAP channel for plugins

Hi,

I've seen in the Markdown Navigator plugin, that plugins can define EAP channels similar to how the Idea does it. Is there any documentation/example code available on how to do so?

I've already noticed that I can choose the channel when uploaded a version to https://plugins.jetbrains.com . However it's unclear to me what the user has to do to switch to a particular channel for my plugin.

Does an" EAP" channel release inherit "Stable" channel releases? Or would users be stuck to an EAP build until I publish a new one?


Thanks,
Holger

 

 

1

Holger, in Markdown Navigator I implemented EAP using the custom plugin repository. A later stable release overrides earlier EAP releases.

I implemented on my web server which returns the plugin description for the EAP or PATCH release:

<?xml version="1.0" encoding="UTF-8"?>
<plugins>
    <plugin id="com.vladsch.idea.multimarkdown" url="https://github.com/vsch/idea-multimarkdown/raw/master/dist/idea-multimarkdown.2.3.2.8.zip" version="2.3.2.8">
        <idea-version since-build="143.2370"/>
        <name>Markdown Navigator</name>
        <change-notes><![CDATA[
            <div xmlns="http://www.w3.org/1999/html"><h3>2.3.2.8 - Bug Fix &amp; Enhancement Release</h3>
                <ul>
                    <li>Add: max image width and default font family settings for use by Copy Markdown to HTML formatted and Export to PDF actions</li>
                    <li>Add: JavaFX WebView state persistence through <code>window.__MarkdownNavigator.getState(&quot;name&quot;)</code> and <code>window.__MarkdownNavigator.setState(&quot;name&quot;, value)</code></li>
                    <li>Add: #388, JavaFX script for GitHub Collapse Markdown script use state persistence for initializing the open/close state of headings. Now collapsed heading are preserved between page refreshes and when opening markdown files.</li>
                    <li>Add: img style <code>width:100%</code> to HTML mime copy and PDF export to scale images instead of clipping them.</li>
                    <li>Fix: paragraph spacing in <code>html_mime_default.css</code></li>
                    <li>Add: PDF export action, menu and toolbar item</li>
                    <li>Fix: highlight on scroll to only exclude typing and backspace edit actions if Highlight on edit is disabled.</li>
                    <li>Fix: Swing preview paragraphs not missing inter-paragraph spacing</li>
                    <li>Fix: add parser option to turn off GFM treatment of list item as loose if blank line follows item paragraph. This is incompatible with GitHub rendering but gives better control of when an item is loose.</li>
                </ul>
            </div>
            ]]></change-notes>
    </plugin>
</plugins>

When EAP distribution is disabled the server will return an empty plugin list:

<?xml version="1.0" encoding="UTF-8"?>
<plugins>
</plugins>

The plugin sets custom plugin repository based on user selection:

class UpdateStream {
    void clearReleaseStream() {
        UpdateSettings settings = UpdateSettings.getInstance();
        List<String> hosts = settings.getStoredPluginHosts();
        ArrayList<String> newHosts = new ArrayList<String>();

        for (String host : hosts) {
            if (host.equalsIgnoreCase(LicenseAgent.patchRelease)) {
            } else if (host.equalsIgnoreCase(LicenseAgent.eapRelease)) {
            } else if (host.equalsIgnoreCase(LicenseAgent.altPatchRelease)) {
            } else if (host.equalsIgnoreCase(LicenseAgent.altEapRelease)) {
            } else {
                newHosts.add(host);
            }
        }

        hosts.clear();
        hosts.addAll(newHosts);
    }

    void setReleaseStream(int releaseStream) {
        UpdateSettings settings = UpdateSettings.getInstance();
        List<String> hosts = settings.getStoredPluginHosts();
        clearReleaseStream();

        if (releaseStream == UpdateStreamType.PATCHES.getIntValue()) {
            hosts.add(LicenseAgent.patchRelease);
        } else if (releaseStream == UpdateStreamType.EAP.getIntValue()) {
            hosts.add(LicenseAgent.eapRelease);
        }
    }
}
0

@Vladimir Thanks a lot for insight on your solution! Out of curiosity, is there a reason why you've decided to implement it on your side rather than using plugins.jetbrains.com's functionality of creating EAP channel and then utilizing link similar to https://plugins.jetbrains.com/plugins/EAP/1347 where EAP is a custom channel name, and 1347 is a plugin ID (1347 is Scala plugin)? Such links give you a list of compatible plugins/updates in the EAP channel to provide to the IDE as a custom repository. I believe @Holgerbrandl can use such link instead of supporting it on their side.

0

@Mikhail, I do not remember if the EAP channel on plugins was available at the time. I implemented the first solution that I could find. Sometimes it is faster to implement than to find information on what exists and how to use it. :) 

I agree that using the standard custom channels for plugins is easier and should be used by Holger.

0

@Vladimir Fair enough :) And yeah, we'll need to document it more in the future (in addition to many other things), I couldn't find much public information about this "recommended way" from our side. Added TODO for me to add it to the SDK docs.

0
Avatar
Permanently deleted user

Thanks very much to both of you Vladimir and Mikhail for you help. 

The simple combobox channel dropdown chooser in the plugin-settings of the Markdown Navigator seems more easy to communicate to users. 

But I also like the simplicity of the channel concept when using plugins.jetbrains.com that works without additional infrastructure. Given that the jetbrains repository already has these channels, why aren't they choosable by the user directly in the plugin manager? Like in my mockup:



The current workflow of first setting up a custom repository and then installing an EAP release from it seems overly complex to me.

@Mikhail: Would a newer release on the stable channel be suggested to a user who installed an EAP release via the custom EAP repository before? Or would he be stuck until a newer EAP release is published on the EAP channel?

Thanks,
Holger

 

0

I used custom repos myself, but I've switched over to using the JetBrains plugin repo now. AFAIK there's no doc on how to use it though, I got the info in the intellij-gradle-plugin gitter channel.

I'm using Gradle to build and deploy. So when I deploy, I use:

publishPlugin {
  username publishUsername
  password publishPassword
  channels publishChannels.split(',')
}

and in my gradle.properties I have:

#publishChannels=eap
#publishChannels=default,eap
publishChannels=dev

I uncomment the line corresponding to the type of build I'd like to perform. Note that release builds go both to the default channel and the eap channel, if you don't do that then users who have your eap channel repository added will not see your release builds.

Users who want EAP builds add a plugin repository as described by Mikhail above. I have a config item in my settings which does that automatically, so users never have to muck around with the URLs etc. I also use a dev channel for one-off builds I'd like users to test, they download those manually from the plugin page and install from disk.

0
Avatar
Permanently deleted user

Thanks Colin. Interesting to hear that you also considered the designed approach as being to complicated and automated the process for the users by adding a config item in the settings. 

Are the sources of your above mentioned plugin public/open-source so that I could inspire myself concerning the config item?

 

0

It's not, but the code is very simple:

public static boolean isUseEapBuilds() {
  List<String> hosts = UpdateSettings.getInstance().getStoredPluginHosts();
  for (String host : hosts) {
    if (host.equals(EAP_REPO)) return true;
  }

  return false;
}

public static void setUseEapBuilds(boolean use) {
  List<String> hosts = UpdateSettings.getInstance().getStoredPluginHosts();

  if (use) {
    if (!hosts.contains(EAP_REPO)) {
      hosts.add(EAP_REPO);
    }
  } else {
    hosts.remove(EAP_REPO);
  }
}
0
Avatar
Permanently deleted user

Nice, that's indeed much less complicated than I expected. Thanks!

0

请先登录再写评论。