==================================================
Packaging jEdit for release
==================================================

This document contains instructions on how to create and release jEdit for distribution, with all of the installers.

The analogous document for releasing plugins is in the jedit SVN repository under the name "pjo/doc/pjo.txt".

Release Workflow
================
Before you read this document, be sure to read first the README.SRC.txt, in the root source directory. It contains instructions on how to get and set up Apache Ant, what the targets mean, and what you need to build each kind of package.

Workflow
--------

1. Execute the BeanShell snippet at the end of this file ("Utilities -> BeanShell -> Evaluate Selection"). This will replace the version tags in this document by actual version numbers for easy copy & paste.

2. Review https://svn.code.sf.net/p/jedit/svn/jEdit[ifbranch]/branches[/ifbranch]/[branch]/doc/CHANGES.txt for formatting errors (like missing newline characters, wrong indentation or empty blocks), fix them and check them in.

3. Tag the sourcecode for release in the SVN repository by doing
        svn copy https://svn.code.sf.net/p/jedit/svn/jEdit[ifbranch]/branches[/ifbranch]/[branch] https://svn.code.sf.net/p/jedit/svn/jEdit/tags/[tag] -m "Tagging [version] for release."
   with the correct version in the second URL and in the commit message

4. To be sure to work with the exact tagged source, check out the newly tagged source in a new directory by doing
        svn checkout https://svn.code.sf.net/p/jedit/svn/jEdit/tags/[tag]
   no matter where. You will find the source in a subfolder [tag] where you executed the command

5. Copy build.properties from your jEdit source directory to the newly created [tag] source directory if needed. If you don't have it, then create it if needed. You find a template called build.properties.sample in the root directory.
   To give an example, in build.properties I customized the following properties:
    - wine.executable=wine
    - winepath.executable=winepath
    - innosetup.compiler.executable=/home/vampire/.wine/drive_c/Programme/Inno Setup 5/ISCC.exe
    - innosetup.via.wine=true
    - gpg.secring=/home/vampire/.gnupg/secring.gpg
   You may not need to customize the same properties than me, e. g. if you are on Windows you don't need to set the three wine properties.
   For further information about what you need to build the source, please read README.SRC.txt in the sources root directory.

6.1. Build the distribution files by doing
          ant dist
     in the [tag] directory
     In the newly created directory [tag]/dist you find [ifdevel]8[/ifdevel][iffinal]13[/iffinal] files:
      - jedit[version]manual-a4.pdf
      - jedit[version]manual-letter.pdf
      - jedit[version]source.tar.bz2
      - jedit[version]install.jar
      - jedit-[version]-noarch-1sao.tgz
      - jedit_[version]_all.deb
      - jedit[version]install.exe or jedit[version]-dist-win-finish.tar.bz2
      - jedit[version]install.dmg or jedit[version]-dist-mac-finish.tar.bz2
[iffinal]      - Packages
      - Packages.gz
      - Packages.bz2
      - Release
      - Release.gpg
[/iffinal]
6.2. If you have jedit[version]-dist-win-finish.tar.bz2 in your [tag]/dist folder you probably don't run a Windows box and don't have wine installed and set up, so please hand over this file to someone (e. g. <Björn "Vampire" Kautler> Vampire@jEdit.org) who does and ask him to unpack the file and run
          ant dist-win-finish
     and to hand over the resulting file jedit[version]install.exe to you. The requirements for this are described in README.SRC.txt

6.3. If you have jedit[version]-dist-mac-finish.tar.bz2 in your [tag]/dist folder you probably don't run a Mac OS X box, so please hand over this file to someone (e. g. Björn "Vampire" Kautler <Vampire@jEdit.org>) who does and ask him to unpack the file and run
          ant dist-mac-finish
     and to hand over the resulting file jedit[version]install.dmg to you. The requirements for this are described in README.SRC.txt

6.4. After you received the final distribution files jedit[version]install.exe and jedit[version]install.dmg you can delete jedit[version]-dist-win-finish.tar.bz2 and jedit[version]-dist-mac-finish.tar.bz2
[iffinal]
6.5. If you don't have Release.gpg, you didn't have setup a GPG secring. Either create a GPG secring, run
          ant dist-sign-deb-Release
     , upload the public key to a public keyserver and make sure your key is mentioned on http://jedit.org/index.php?page=download&platform=unix#option_two so the users know the key is valid for signing jEdit releases. Alternatively send Release to someone whose key is already mentioned on the download page (e. g. Björn "Vampire" Kautler <Vampire@jEdit.org>) and ask him to put Release in the dist folder, to run
          ant dist-sign-deb-Release
     and to hand over the resulting file Release.gpg to you. The second way is preferable if you only create a release once or from time to time as a new key means the user will get confused and has to react for verifying and installing the new key.
[/iffinal]
7. - Connect to the SourceForge servers via one of the methods described in https://sourceforge.net/apps/trac/sourceforge/wiki/Release%20files%20for%20download
   - Add the sub-folder "[version]" under "/home/frs/project/j/je/jedit/jedit[ifdevel]-devel[/ifdevel]"
   - Upload the 8 final distribution files [iffinal]starting with "jedit" [/iffinal]to the newly created folder on the SourceForge servers
[iffinal]   - Upload the 5 remaining distribution files not starting with "jedit" to the folder "/home/frs/project/j/je/jedit" on the SourceForge servers.
[/iffinal]
8. - Go to https://sourceforge.net/projects/jedit/files/jedit[ifdevel]-devel[/ifdevel]/[version]/
   - Make the following settings for each file after clicking on the respective "i" icon
        - jedit_[version]_all.deb
            - Download Button: Debian Installer
            - Default Download For: <none>
        - jedit[version]source.tar.bz2
            - Download Button: Source Package
            - Default Download For: <none>
        - jedit[version]install.jar
            - Download Button: Java based Installer
            - Default Download For: [ifdevel]<none>[/ifdevel][iffinal]linux, bsd, solaris, others[/iffinal]
        - jedit[version]manual-letter.pdf
            - Download Button: Manual in Letter Paper size
            - Default Download For: <none>
        - jedit[version]manual-a4.pdf
            - Download Button: Manual in A4 Paper size
            - Default Download For: <none>
        - jedit[version]install.dmg
            - Download Button: Mac OS X Installer
            - Default Download For: [ifdevel]<none>[/ifdevel][iffinal]mac[/iffinal]
        - jedit[version]install.exe
            - Download Button: Windows Installer
            - Default Download For: [ifdevel]<none>[/ifdevel][iffinal]windows[/iffinal]
        - jedit-[version]-noarch-1sao.tgz
            - Download Button: Slackware Installer
            - Default Download For: <none>

9. Update the website in the following places and also update this state in SVN:
    - Open sftp://[sourceForgeUsername],jedit@web.sourceforge.net/home/project-web/jedit/htdocs/download.html e. g. in jEdit with installed FTP plugin and update the website for the new release, means the filenames, filesizes and amount of pages in the User's Guides
    - Open sftp://[sourceForgeUsername],jedit@web.sourceforge.net/home/project-web/jedit/htdocs/jEdit-version.txt e. g. in jEdit with installed FTP plugin and update the versions in the file, which is needed by the LatestVersion Plugin
    - Open sftp://[sourceForgeUsername],jedit@web.sourceforge.net/home/project-web/jedit/htdocs/CHANGES[major][minor].txt e. g. in jEdit with installed FTP plugin and copy the contents of [tag]/doc/CHANGES.txt to this file
    - Open sftp://[sourceForgeUsername],jedit@web.sourceforge.net/home/project-web/jedit/htdocs/index.php e. g. in jEdit with installed FTP plugin and update the version number and the Last Site Update date
    - Open sftp://[sourceForgeUsername],jedit@web.sourceforge.net/home/project-web/jedit/htdocs/devel.html e. g. in jEdit with installed FTP plugin and add a line for [version] in the Release Schedule

10. Update the plugin wizard
     - Go to http://plugins.jedit.org/wiz/release_list.php?package_id=24
     - Find or create the entry for this jEdit Release
          The entry may already exist but have an invalid date
          if a plugin was released that depends on it.
     - Switch "Head of Branch" to "[ifdevel]devel[/ifdevel][iffinal]main[/iffinal]"
     - Check the "Remove" checkbox for the jEdit dependency
     - Switch the "Low Version" of the JDK dependency to "1.8 [jdk-1.8]"
     - Click "Update Dependencies"
     - Click "Create Release"

11. Send an announcement eMail to the jEdit-announce list. The announcement should contain some announcing text and in the end the contents of [tag]/doc/CHANGES.txt for this release.
    You have to be set up to be able to post to jEdit-announce list.
    The mail should automatically get forwarded to the jedit-users list, but for that you have to be subscribed to that list too.

12. Ask Vampire <Vampire@jEdit.org> (Vampire0@#jEdit@chat.freenode.net) to update the topic of the IRC Channel

13. Spread the word about the new release whereever possible e. g.:
     - On Twitter
     - On Google+
     - On Facebook
     - On the jEdit Community page
     - Send a mail to the Community Growth Hacker of SourceForge for promotion of the release, currently this is Rich Bowen <communityteam@sourceforge.net>
     - Send a mail to Heise for inclusion in the weekly Heise Developer Snapshots at developer@ix.de

14. Delete the [tag] folder

15. Update the version number on the release branch
     - Add the following section to doc/CHANGES.txt

{{{ Version [nextVersion]

Thanks to  for contributing to this release.

{{{ Bug Fixes


}}}
{{{ Miscellaneous


}}}
{{{ API Changes


}}}
{{{ Editing


}}}

}}}
     - Update the build number in org/gjt/sp/jedit/jEdit.java getBuild() method to
            return "[nextBuild]";
     - Submit your changes by doing
            svn commit -m "Update the version number to [nextVersion]"
       in the root source directory
[ifbranch]
16. If the release is from the latest release branch, clean up doc/CHANGES.txt on trunk.
     - Update the version number which is the base of CHANGES.txt.
            "changes since jEdit [version]"
     - Remove all entries which have been released in [version].
       The entries to be removed are tagged with "[merged into [branch]]".
     - Submit your changes by doing
            svn commit -m "Update the base version of CHANGES.txt to [version]" doc/CHANGES.txt
       in trunk.
[/ifbranch]
====================================================================================================
import java.util.regex.Pattern;
file = new File(new File(buffer.getPath()).getParentFile(), "../org/gjt/sp/jedit/jEdit.java");
fileChars = new char[file.length()];
reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));
reader.read(fileChars, 0, fileChars.length);
reader.close();
pattern = Pattern.compile("public static String getBuild\\(\\)[^}]+return \"([^\"]{11})\"");
matcher = pattern.matcher(new String(fileChars));
matcher.find();
build = matcher.group(1);
major = Integer.parseInt(build.substring(0,2));
minor = Integer.parseInt(build.substring(3,5));
beta = Integer.parseInt(build.substring(6,8));
micro = Integer.parseInt(build.substring(9,11));
branch = Macros.input(view, "Current branch or \"trunk\" (\"t\" is also possible)?", major + "." + minor + ".x");
if (branch == null) {
    return;
}
branch = "t".equals(branch) ? "trunk" : branch;
tag = "jedit-"
      + major
      + "-" + minor
      + (beta != 99 ? "-pre" + beta : "-" + micro);
version = major
          + "." + minor
          + (beta != 99 ? "pre" + beta : "." + micro);
nextVersion = major
              + "." + minor
              + (beta != 99 ? "pre" + (beta + 1) : "." + (micro + 1));
nextBuild = String.format("%02d.%02d.%02d.%02d",
                          new Object[] { Integer.valueOf(major),
                                         Integer.valueOf(minor),
                                         Integer.valueOf(beta == 99 ? beta : beta + 1),
                                         Integer.valueOf(beta == 99 ? micro + 1 : micro) });
sourceForgeUsername = Macros.input(view, "Your SourceForge Username?", "vampire0");
if (sourceForgeUsername == null) {
    return;
}
SearchAndReplace.setBeanShellReplace(false);
SearchAndReplace.setIgnoreCase(false);
SearchAndReplace.setRegexp(false);
SearchAndReplace.setSearchFileSet(new CurrentBufferSet());
buffer.beginCompoundEdit();
SearchAndReplace.setSearchString("[branch]");
SearchAndReplace.setReplaceString(branch);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[tag]");
SearchAndReplace.setReplaceString(tag);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[version]");
SearchAndReplace.setReplaceString(version);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[major]");
SearchAndReplace.setReplaceString(Integer.toString(major));
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[minor]");
SearchAndReplace.setReplaceString(Integer.toString(minor));
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[nextVersion]");
SearchAndReplace.setReplaceString(nextVersion);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[nextBuild]");
SearchAndReplace.setReplaceString(nextBuild);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("[sourceForgeUsername]");
SearchAndReplace.setReplaceString(sourceForgeUsername);
SearchAndReplace.replaceAll(view);
SearchAndReplace.setRegexp(true);
SearchAndReplace.setBeanShellReplace(true);
SearchAndReplace.setSearchString("\\[ifdevel\\]((?:.|\n)*?)\\[/ifdevel\\]");
SearchAndReplace.setReplaceString(beta != 99 ? "_1" : "");
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("\\[iffinal\\]((?:.|\n)*?)\\[/iffinal\\]");
SearchAndReplace.setReplaceString(beta != 99 ? "" : "_1");
SearchAndReplace.replaceAll(view);
SearchAndReplace.setSearchString("\\[ifbranch\\]((?:.|\n)*?)\\[/ifbranch\\]");
SearchAndReplace.setReplaceString(branch.equals("trunk") ? "" : "_1");
SearchAndReplace.replaceAll(view);
textArea.replaceSelection("Variables replaced\n");
buffer.endCompoundEdit();
====================================================================================================

:wrap=soft:maxLineLen=0:folding=indent:
