KDP(電子出版)のメモ 急急如律令

Amazon Kindleダイレクト・パブリッシングでの電子出版や電子書籍の作成販売について、文章やイラストの作成や編集方法について書いています。

jpackageのmsi作成処理をGitHub Actionsに追加するには

jpackageのmsi作成処理をgithub actionに追加するには

chatgpt:

できます。現在の構成を見ると、Linux の nightly build はそのまま残し、Windows 用に別 job を追加して jpackage --type msi を実行するのが一番自然です。

現在の nightly.yml は ubuntu-latest で JAR を作っているため、MSIだけは windows-latest で作る必要があります。GitHub Actions では Windows runner が利用できます。(GitHub Docs)

また、現在の build.gradle は Java 21 の jar タスクと create_run_jar を使っているので、まずは既存の create_run_jar の成果物をそのまま jpackage に渡す形が変更が少ないです。nightly.yml でも現在 gradle create_run_jar → build/libs/AozoraEpub3.jar を out/ にコピーしています。

まずおすすめする構成

今の

Ubuntu
  ↓
JAR作成
  ↓
artifact

に加えて、

Windows
  ↓
JAR作成
  ↓
jpackage
  ↓
AozoraEpub3-1.1.1.31.msi
  ↓
artifact

を追加します。

nightly.yml

例えばこうできます。

name: Nightly Build

on:
  - push
  - workflow_dispatch

jobs:
  build_artifacts:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - name: Get version from source code
        run: |
          >> $GITHUB_ENV echo PKG_VER=$(egrep 'VERSION\s+=' src/AozoraEpub3.java | awk -F '"' '{print $2}')

      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'zulu'
          cache: 'gradle'

      - run: gradle build

      - run: mkdir -p bin

      - run: gradle create_run_jar

      - run: cp -v build/libs/AozoraEpub3.jar out/

      - run: cp -vr lib/LICENSE out/

      - uses: actions/upload-artifact@v4
        with:
          name: AozoraEpub3-${{ env.PKG_VER }}
          path: out/


  build_msi:
    runs-on: windows-latest

    steps:
      - uses: actions/checkout@v4

      - name: Get version from source code
        shell: bash
        run: |
          echo "PKG_VER=$(grep -E 'VERSION\s+=' src/AozoraEpub3.java | awk -F '"' '{print $2}')" >> "$GITHUB_ENV"

      - uses: actions/setup-java@v4
        with:
          java-version: '21'
          distribution: 'zulu'
          cache: 'gradle'

      - name: Build JAR
        shell: cmd
        run: gradlew.bat create_run_jar

      - name: Prepare jpackage input
        shell: pwsh
        run: |
          New-Item -ItemType Directory -Force -Path jpackage-input
          Copy-Item build/libs/AozoraEpub3.jar jpackage-input/
          Copy-Item AozoraEpub3.ico jpackage-input/
          Copy-Item -Recurse web jpackage-input/ -ErrorAction SilentlyContinue
          Copy-Item -Recurse profiles jpackage-input/ -ErrorAction SilentlyContinue

      - name: Create MSI
        shell: cmd
        run: >
          jpackage
          --type msi
          --win-menu
          --win-dir-chooser
          --win-shortcut
          --win-shortcut-prompt
          --copyright "kyukyunyorituryo"
          --icon AozoraEpub3.ico
          --app-version %PKG_VER%
          --description "改造版AozoraEpub3 青空文庫テキストePub3変換"
          -n "AozoraEpub3"
          --main-jar AozoraEpub3.jar
          --input jpackage-input
          --dest out

      - name: Upload MSI
        uses: actions/upload-artifact@v4
        with:
          name: AozoraEpub3-${{ env.PKG_VER }}-msi
          path: out/*.msi

ただし、ここには1点確認が必要です。

あなたの実際のリポジトリで、

web/
profiles/
AozoraEpub3.ico

がどこにあるかです。

現在の build.gradle では resources に src を指定しています。

resources {
    srcDirs = ["src"]
}

なので、web や profiles が src 以下に入っているなら、上の

Copy-Item -Recurse web jpackage-input/

は変える必要があります。


さらにおすすめ:build.gradle に jpackage タスクを作る

個人的には、今回はこちらの方をおすすめします。

現在、

ant.importBuild 'ant.xml'

もありますし、既存のビルド処理をGradleから呼び出しているので、jpackageもGradleタスクにしてしまうと管理しやすいです。

例えば、

tasks.register('jpackageMsi', Exec) {
    dependsOn 'create_run_jar'

    def inputDir = layout.buildDirectory.dir('jpackage-input').get().asFile
    def outputDir = layout.buildDirectory.dir('jpackage').get().asFile

    doFirst {
        inputDir.mkdirs()
        outputDir.mkdirs()

        copy {
            from 'build/libs/AozoraEpub3.jar'
            into inputDir
        }

        copy {
            from 'AozoraEpub3.ico'
            into inputDir
        }
    }

    commandLine 'jpackage',
            '--type', 'msi',
            '--win-menu',
            '--win-dir-chooser',
            '--win-shortcut',
            '--win-shortcut-prompt',
            '--copyright', 'kyukyunyorituryo',
            '--icon', 'AozoraEpub3.ico',
            '--app-version', '1.1.1.31',
            '--description', '改造版AozoraEpub3 青空文庫テキストePub3変換',
            '-n', 'AozoraEpub3',
            '--main-jar', 'AozoraEpub3.jar',
            '--input', inputDir.absolutePath,
            '--dest', outputDir.absolutePath
}

そしてGitHub Actionsは、

- name: Create MSI
  run: gradlew.bat jpackageMsi

だけにできます。


ただしバージョンは固定しない方がいい

現在のコマンドでは、

--app-version 1.1.1.31

と固定されています。

一方、nightly.yml はソースコードから

PKG_VER

を取得しています。

なのでGradle側でもバージョンをソースから取得するか、GitHub Actionsから渡す方がいいです。

例えば、

- name: Create MSI
  run: gradlew.bat jpackageMsi -PpkgVersion=${{ env.PKG_VER }}

として、

def pkgVersion = project.findProperty('pkgVersion') ?: '1.1.1.31'

とします。

そして、

'--app-version', pkgVersion,

とします。

これなら、

src/AozoraEpub3.java
        ↓
VERSION
        ↓
PKG_VER
        ↓
jpackage --app-version
        ↓
AozoraEpub3-1.1.1.31.msi

と一元化できます。


WiXについて

jpackage --type msi はWindows側でMSIを生成するためのWiX環境が必要です。

現在のGitHub-hosted windows-2025 イメージには WiX Toolset 3.14.1 が既に入っています。(GitHub)

そのため、まずは

runs-on: windows-latest

で試すのが簡単です。

jpackage 自体はJDK 21に含まれているので、既存の

actions/setup-java@v4
java-version: '21'

で使えます。


なお、あなたの現在の構成なら「別ジョブ」がいい

既存の

build_artifacts:
  runs-on: ubuntu-latest

をWindowsに変更するのではなく、

build_artifacts
    └─ Ubuntu
       └─ JAR

build_msi
    └─ Windows
       └─ JAR
       └─ jpackage
       └─ MSI

とするのがいいです。

理由は、jpackage は対象OS上でパッケージを作るという前提だからです。Linux runnerでWindows MSIを作る構成にするより、Windows runnerで直接作った方が単純です。

また、最近のGitHub ActionsのWindows runnerにはWiXが含まれているため、まずは追加インストールなしで試せます。(GitHub)

次にやるなら、実際の build.gradle の create_run_jar と ant.xml の構成に合わせて、jpackageMsi タスクを最小変更で追加するのがよいです。 今回アップロードされた build.gradle では ant.xml 側の処理が見えていないため、そこだけ確認できれば、かなり正確に組めます。

jpackage で作ったMSIをインストールして起動したときの Failed to launch JVM なら、まず疑うべきなのは アプリ本体ではなく、jpackageが同梱したJRE/JVMの起動設定です。

今回の構成だと、特に --main-jar と --input の中身を確認したいです。

まず確認したいこと

MSIをインストールした後、インストール先に通常、

AozoraEpub3/
├─ app/
│  ├─ AozoraEpub3.jar
│  └─ ...
├─ runtime/
│  └─ bin/
│     └─ java.exe
└─ AozoraEpub3.exe

のような構成ができます。

そこで インストール先の app フォルダに何が入っているか確認してください。

特に今回のjpackageコマンドが

--main-jar AozoraEpub3.jar
--input C:\Users\Owner\Desktop\AozoraEpub3-1.1.1b31Q

なら、入力ディレクトリには最低限、

AozoraEpub3-1.1.1b31Q/
└─ AozoraEpub3.jar

が必要です。


一番重要なのは、コマンドラインからJARが起動するか

MSIを作る前に、同じJARについて、

java -jar AozoraEpub3.jar

が正常に動くか確認してください。

これが動くのにMSIだけ

Failed to launch JVM

になるなら、jpackage 側の問題にかなり絞れます。

逆に、

java -jar AozoraEpub3.jar

でも起動しないなら、JAR側の問題です。


また、jpackageで直接試す

MSIではなく app-image を作ると原因を切り分けやすいです。

jpackage ^
  --type app-image ^
  --win-menu ^
  --win-dir-chooser ^
  --win-shortcut ^
  --win-shortcut-prompt ^
  --copyright "kyukyunyorituryo" ^
  --icon AozoraEpub3.ico ^
  --app-version 1.1.1.31 ^
  --description "改造版AozoraEpub3 青空文庫テキストePub3変換" ^
  -n "AozoraEpub3" ^
  --main-jar AozoraEpub3.jar ^
  --input C:\Users\Owner\Desktop\AozoraEpub3-1.1.1b31Q

生成された、

AozoraEpub3\
    AozoraEpub3.exe

を直接起動します。

これでも

Failed to launch JVM

なら、MSIではなく jpackageのアプリイメージ生成段階の設定を調べるべきです。


今回かなり気になる点

以前のコードで、

System.getProperty("jpackage.app-path")

を使ってjpackage環境を判定していましたが、これは JVMが正常に起動した後のJavaコードなので、今回の

Failed to launch JVM

より前の段階で失敗しているなら、これは原因ではありません。

つまり、

EXE
 ↓
JVM起動 ← ★ここで失敗
 ↓
AozoraEpub3.jar
 ↓
main()
 ↓
jpackage.app-path判定

なので、まずJVM起動自体を確認する必要があります。


もし今回の Failed to launch JVM が GitHub ActionsでMSIを作った後にインストールしたWindowsで発生しているのであれば、さらに jpackage の実行ログと、生成された app フォルダの内容を見るのが早いです。

jpackage を実行したときのコマンド全文と、起動時に表示される Failed to launch JVM の画面(またはログ)を貼ってもらえれば、原因をかなり絞れます。 なるほど。「Failed to launch JVM」の原因として、ant.xmlで行っていたファイルコピーがjpackage側では再現されていない可能性が高いです。

jpackageは基本的に、

--input
    AozoraEpub3.jar

のように指定したファイルしかアプリイメージへ入れません。 ant.xmlで例えば、

web/
profiles/
*.properties
*.ini
images/
lib/

などをコピーしていたなら、そのコピー処理をjpackage用のinputディレクトリ作成時に再現する必要があります。

今回の構成なら、MSI作成前に例えば、

build/jpackage-input/
├─ AozoraEpub3.jar
├─ web/
├─ profiles/
├─ images/
└─ その他必要ファイル

を作ってから、

jpackage --input build/jpackage-input ...

とするのがよいです。

特に重要なのは、ant.xmlのコピー処理をそのままGradleまたはGitHub Actionsへ移植することです。

もし ant.xml をこちらに渡してもらえれば、そこに書かれている <copy> や <fileset> を確認して、現在のGradle/GitHub Actionsに最小限の変更で組み込む形にできます。 はい。ant.xmlを見ると、原因がかなりはっきりしました。

create_run_jar は単に AozoraEpub3.jar を作っているだけではなく、実行に必要な大量の外部ファイルを out/ にコピーしています。例えば gaiji、presets、template、web、各種 chuki_*.txt などです。

特に重要なのはこの部分です。

<copy file="${dir.buildfile}/gaiji/convert.pe" todir="${dir.jarfile}/gaiji"/>
...
<copy file="${dir.buildfile}/presets/kindle_fire.ini" todir="${dir.jarfile}/presets"/>
...
<copy file="${dir.buildfile}/template/mimetype" todir="${dir.jarfile}/template/"/>
...
<copy file="${dir.buildfile}/web/extract_sample.txt" todir="${dir.jarfile}/web/"/>

そして最後に、

<copy file="${dir.buildfile}/AozoraEpub3.ico" todir="${dir.jarfile}"/>
<copy file="${dir.buildfile}/chuki_alt.txt" todir="${dir.jarfile}"/>
...
<copy file="${dir.buildfile}/README_Changes.txt" todir="${dir.jarfile}"/>

までコピーしています。

つまり、先ほどのMSI作成方法で

AozoraEpub3.jar

だけを jpackage --input に渡していたなら、従来のAntビルドと全く同じ実行環境になっていません。

一番簡単な修正

むしろ既存の ant.xml を利用するのがよいです。

現在、

gradle create_run_jar

を実行しているなら、Windows側でも

gradlew.bat create_run_jar

として、その結果の out/ をそのまま jpackage の --input に渡します。

つまり、

プロジェクト
 ├─ out/
 │   ├─ AozoraEpub3.jar
 │   ├─ gaiji/
 │   ├─ presets/
 │   ├─ template/
 │   ├─ web/
 │   ├─ chuki_alt.txt
 │   ├─ chuki_ivs.txt
 │   ├─ ...
 │   └─ AozoraEpub3.ico

という従来の構成を作ってから、

jpackage ^
  --type msi ^
  --input out ^
  --main-jar AozoraEpub3.jar ^
  ...

とするのが最小変更です。

ただし、jpackageでは --input の中身がそのままアプリの app ディレクトリへコピーされるので、これは今回の目的にも非常に合っています。

ただし一つ注意

Antの処理では out/lib に依存JARをコピーする部分はコメントアウトされています。

そのため、現在の AozoraEpub3.jar が依存ライブラリをどう扱っているかは、build.gradle 側の create_run_jar 実装も確認した方がいいです。

結論としては、MSI用に別途大量の <copy> を書き直す必要はありません。

gradle create_run_jar
        ↓
      out/
        ↓
jpackage --input out
        ↓
      MSI

という流れにするのが、既存のAntビルドを最も忠実に利用できる方法です。 そういう構成なら、原因がかなり明確です。

もともとの ant.xml は「JARを作る」だけでなく、JARの外側に必要な実行時ファイル一式を out/ に配置する役割も持っていたわけですね。

一方、現在は、

ant.xml
  ↓
AozoraEpub3.jar
  +
gaiji/
presets/
template/
web/
chuki_*.txt
...

という構成から、

Gradle
  ↓
fat JAR
  ↓
AozoraEpub3.jar

へ変更した。

そのため、fat JAR化したことによってJavaライブラリはJAR内に入ったとしても、ant.xmlがコピーしていた「アプリ固有の外部ファイル」は自動的には移行されません。

つまりMSIの問題はここ

jpackageに渡しているものが、

AozoraEpub3.jar

だけだと、

gaiji/
presets/
template/
web/
chuki_alt.txt
chuki_ivs.txt
chuki_latin.txt
chuki_tag.txt
chuki_tag_suf.txt
chuki_utf.txt

などが存在しません。

ant.xmlではこれらを明示的にコピーしていたので、従来の実行環境には存在していました。

したがって、fat JAR化した現在のGradle構成でも、この「アプリ固有ファイルの配置」は別途必要です。


一番変更が少ない方法

Gradleでfat JARを作る処理に、

out/
 ├─ AozoraEpub3.jar
 ├─ gaiji/
 ├─ presets/
 ├─ template/
 ├─ web/
 ├─ chuki_alt.txt
 ├─ chuki_ivs.txt
 ├─ chuki_latin.txt
 ├─ chuki_tag.txt
 ├─ chuki_tag_suf.txt
 └─ chuki_utf.txt

を作る処理を追加します。

そしてjpackageは、

jpackage ^
  --type msi ^
  --input out ^
  --main-jar AozoraEpub3.jar ^
  ...

とします。

つまり、

Gradle fat JAR
      ↓
      ├── AozoraEpub3.jar
      ├── gaiji/
      ├── presets/
      ├── template/
      ├── web/
      └── chuki_*.txt
             ↓
          jpackage
             ↓
          MSI

です。

重要なのは

ant.xmlをもう実行する必要はありません。

ant.xmlは「昔のJAR作成+必要ファイルコピー」の仕組みなので、現在は

JAR作成 → Gradle
必要ファイルコピー → Gradle
MSI作成 → jpackage

と役割を分けるのが自然です。

また、fat JARにしたことで lib/*.jar を外に置く必要もなくなっているはずなので、ant.xmlの依存ライブラリコピー部分をそのまま再現する必要もありません。

次に確認したいのは、現在の build.gradle の create_run_jar 周辺です。 そこに最小限の copy を追加すれば、ant.xmlのコピー処理をGradleへ移せます。 できます。むしろ今回の目的なら、ant.xmlをそのまま利用して、Gradleでfat JARを作った後にant.xmlの「ファイルコピー処理」だけを実行する方法が一番変更が少ないです。

ただし、ant.xml の create_run_jar はJAR自体も作るので、そのターゲットをそのまま呼ぶと、Gradleで作ったfat JARを上書きしてしまいます。

したがって、ant.xml にあるコピー処理を実行する専用ターゲットを追加するのが安全です。

例えば、

<target name="copy_runtime_files">
    <copy todir="${dir.jarfile}/gaiji">
        ...
    </copy>

    <copy todir="${dir.jarfile}/presets">
        ...
    </copy>

    <copy todir="${dir.jarfile}/template">
        ...
    </copy>

    <copy todir="${dir.jarfile}/web">
        ...
    </copy>

    <copy file="..." todir="${dir.jarfile}"/>
    ...
</target>

のように、既存の create_run_jar に入っている <copy> をそのまま移す形です。

そしてGradleからAntを呼びます。

tasks.register("copyRuntimeFiles") {
    doLast {
        ant.antfile("ant.xml", target: "copy_runtime_files")
    }
}

そのうえで、

gradle build
      ↓
fat JAR作成
      ↓
gradle copyRuntimeFiles
      ↓
out/
 ├─ AozoraEpub3.jar       ← Gradleのfat JAR
 ├─ gaiji/
 ├─ presets/
 ├─ template/
 ├─ web/
 ├─ chuki_alt.txt
 ├─ chuki_ivs.txt
 ├─ chuki_latin.txt
 ├─ chuki_tag.txt
 ├─ chuki_tag_suf.txt
 └─ chuki_utf.txt
      ↓
jpackage --input out

という流れにできます。

さらに変更を少なくするなら

ant.xml の既存の create_run_jar を、

<target name="create_run_jar" depends="copy_runtime_files">
    ...
</target>

のように変更する方法もありますが、今回はGradle側ですでにfat JARを作っているので、create_run_jar は従来の用途として残して、MSI用には copy_runtime_files を追加するほうが分かりやすいです。

特に今回の ant.xml は、gaiji、presets、template、web、各種 chuki_*.txt などのコピー処理がすでに完成しているので、そのコピー内容をGradleへ書き直す必要はありません。既存のAnt処理をそのまま再利用できます。

もし現在の build.gradle を基準にするなら、create_run_jar をどのように変更すれば「fat JAR → ant.xmlのコピー → jpackage」になるか、実際のGradleコードに合わせて最小変更で書けます。 はい。今回の構成なら、ant.xmlのJAR作成処理を削除して、コピー処理だけ残すのが一番簡単だと思います。

現在は、

Gradle
 └─ fat JARを作成
       ↓
ant.xml
 └─ 必要ファイルをout/へコピー
       ↓
jpackage
 └─ out/をMSI化

にすればよいです。

ant.xmlをこうする

現在の

<target name="create_run_jar">
    <jar destfile="${dir.jarfile}/AozoraEpub3.jar">
        ...
    </jar>

    <copy ... />
    <copy ... />
    ...
</target>

から、<jar> 部分だけ削除して、

<target name="copy_runtime_files">
    <copy ... />
    <copy ... />
    ...
</target>

とします。

つまり、既存の <copy> 処理は一切変更しない。

ant.xml にある out/AozoraEpub3.jar の生成部分は、現在のGradleのfat JAR生成と役割が重複しています。元のAnt処理では bin/ をJARに入れていましたが、現在はGradleがfat JARを作るため、ここを残す意味がありません。

Gradleから呼ぶ

例えば、

tasks.register("copyRuntimeFiles") {
    dependsOn("jar")

    doLast {
        ant.antfile("ant.xml", target: "copy_runtime_files")
    }
}

そしてMSI作成前に、

gradle copyRuntimeFiles

とします。

ただし、現在のfat JARの出力先が build/libs/AozoraEpub3.jar なら、Antの out/ にコピーする処理だけ1行追加すればよいです。

copy {
    from jar
    into "out"
}

最終的には、

build/libs/AozoraEpub3.jar
        ↓
      out/
        ├── AozoraEpub3.jar
        ├── gaiji/
        ├── presets/
        ├── template/
        ├── web/
        └── chuki_*.txt
        ↓
     jpackage
        ↓
      MSI

となります。

なので、今回なら「AntをGradleに移植する」より、「AntからJAR生成部分だけ捨てて、既存のコピー処理をそのまま再利用する」のが最小変更です。 はい。Ant側はJAR作成をやめてコピー処理だけにし、Gradleのfat JARを out/ に置いてから、Antのコピー処理を実行して、その out/ をそのままjpackageに渡す形なら、かなりシンプルです。

完成形は以下です。

tasks.register('jpackageMsi', Exec) {
    dependsOn 'create_run_jar'

    def inputDir = file('out')
    def outputDir = layout.buildDirectory.dir('jpackage').get().asFile

    doFirst {
        inputDir.mkdirs()
        outputDir.mkdirs()

        // Gradleで作成したfat JARをoutへ配置
        copy {
            from 'build/libs/AozoraEpub3.jar'
            into inputDir
        }

        // ant.xmlの実行時ファイルコピー処理
        ant.antfile('ant.xml', target: 'copy_runtime_files')
    }

    commandLine 'jpackage',
            '--type', 'msi',
            '--win-menu',
            '--win-dir-chooser',
            '--win-shortcut',
            '--win-shortcut-prompt',
            '--copyright', 'kyukyunyorituryo',
            '--icon', 'AozoraEpub3.ico',
            '--app-version', '1.1.1.33',
            '--description', '改造版AozoraEpub3 青空文庫テキストePub3変換',
            '-n', 'AozoraEpub3',
            '--main-jar', 'AozoraEpub3.jar',
            '--input', inputDir.absolutePath,
            '--dest', outputDir.absolutePath
}

そして ant.xml は、JAR生成部分を削除して、

<target name="copy_runtime_files">

    <!-- ここに元のcreate_run_jarにあったcopy処理をそのまま残す -->

</target>

とします。

ただし、1点だけ重要です。

元の ant.xml のコピー先は、

${dir.jarfile}

で、元ファイルでは

<property name="dir.jarfile" location="./out"/>

となっています。

そのため、上記のGradleでは、

out/

をjpackageの入力ディレクトリにしています。

最終的に、

out/
├── AozoraEpub3.jar       ← Gradleのfat JAR
├── gaiji/
├── presets/
├── template/
├── web/
├── chuki_alt.txt
├── chuki_ivs.txt
├── chuki_latin.txt
├── chuki_tag.txt
├── chuki_tag_suf.txt
├── chuki_utf.txt
├── LICENSE.txt
└── ...

となります。

元のAntがコピーしていた gaiji、presets、template、web、各種 chuki_*.txt などもそのまま残せます。

さらに1つ直した方がいいところ

現在の

copy {
    from 'AozoraEpub3.ico'
    into inputDir
}

は不要です。

jpackageの

'--icon', 'AozoraEpub3.ico',

はjpackageを実行する側から見たパスなので、inputDir にコピーする必要はありません。

したがって、完成形はこれで十分です。

tasks.register('jpackageMsi', Exec) {
    dependsOn 'create_run_jar'

    def inputDir = file('out')
    def outputDir = layout.buildDirectory.dir('jpackage').get().asFile

    doFirst {
        inputDir.mkdirs()
        outputDir.mkdirs()

        copy {
            from 'build/libs/AozoraEpub3.jar'
            into inputDir
        }

        ant.antfile('ant.xml', target: 'copy_runtime_files')
    }

    commandLine 'jpackage',
            '--type', 'msi',
            '--win-menu',
            '--win-dir-chooser',
            '--win-shortcut',
            '--win-shortcut-prompt',
            '--copyright', 'kyukyunyorituryo',
            '--icon', 'AozoraEpub3.ico',
            '--app-version', '1.1.1.33',
            '--description', '改造版AozoraEpub3 青空文庫テキストePub3変換',
            '-n', 'AozoraEpub3',
            '--main-jar', 'AozoraEpub3.jar',
            '--input', inputDir.absolutePath,
            '--dest', outputDir.absolutePath
}

これならfat JARの作成はGradle、既存のリソース配置はant.xml、MSI化はjpackageという役割分担になり、既存のAntのコピー処理をほぼそのまま利用できます。 はい。nightly.yml も create_run_jar から変更した方がよいです。

現在は役割が変わっているので、

以前
create_run_jar
  └─ AntでJAR作成+必要ファイルコピー

現在
Gradle
  ├─ fat JAR作成
  └─ Antで必要ファイルコピー

に合わせるべきです。

ただし、create_run_jar 自体を全部なくす必要はありません。既存のGradleタスクがfat JARを作るタスクなら、それを直接使うのがよいです。

たとえば現在のnightly.ymlが、

- run: gradle build
- run: mkdir -p bin
- run: gradle create_run_jar
- run: cp -v build/libs/AozoraEpub3.jar out/
- run: cp -vr lib/LICENSE out/

なら、基本的には、

- run: gradle build
- run: mkdir -p out
- run: gradle copy_runtime_files
- run: cp -v build/libs/AozoraEpub3.jar out/

という流れにします。

ただし順番は、fat JARを out/ にコピーしてから copy_runtime_files を実行しても問題ありません。

おすすめは、

- run: gradle build
- run: mkdir -p out
- run: cp -v build/libs/AozoraEpub3.jar out/
- run: gradle copy_runtime_files

です。

すると、

gradle build
    ↓
build/libs/AozoraEpub3.jar
    ↓
out/AozoraEpub3.jar
    ↓
gradle copy_runtime_files
    ↓
out/
 ├─ AozoraEpub3.jar
 ├─ gaiji/
 ├─ presets/
 ├─ template/
 ├─ web/
 ├─ chuki_*.txt
 └─ ...

となります。

そしてMSI側も同じ out/ を使えば、

nightly.yml
    ↓
Gradle fat JAR
    ↓
out/ ← Antの既存コピー処理
    ↓
jpackage --input out

で統一できます。

なので、nightly.yml の create_run_jar は copy_runtime_files に変更する方向でよいです。

ただし、今の build.gradle にある create_run_jar が実際には何をしているかによって、gradle build だけでfat JARが完成するのか、別タスクが必要なのかが変わります。そこだけ確認してから最終形を決めるのが安全です。