test: fix tests #207
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build | |
| on: | |
| push: | |
| branches: | |
| - dev | |
| - master | |
| pull_request: | |
| branches: | |
| - dev | |
| - master | |
| env: | |
| CICD_REPO_SLUG: jindrapetrik/jpexs-decompiler | |
| GITHUB_USER: jindrapetrik | |
| GITHUB_ACCESS_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| permissions: | |
| contents: write | |
| id-token: write | |
| jobs: | |
| compute-version: | |
| name: Compute version | |
| runs-on: windows-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| outputs: | |
| doRelease: ${{ steps.vars.outputs.doRelease }} | |
| verMajor: ${{ steps.vars.outputs.verMajor }} | |
| verMinor: ${{ steps.vars.outputs.verMinor }} | |
| verRelease: ${{ steps.vars.outputs.verRelease }} | |
| verBuild: ${{ steps.vars.outputs.verBuild }} | |
| verRevision: ${{ steps.vars.outputs.verRevision }} | |
| verLong: ${{ steps.vars.outputs.verLong }} | |
| verRaw: ${{ steps.vars.outputs.verRaw }} | |
| verShort: ${{ steps.vars.outputs.verShort }} | |
| verDebug: ${{ steps.vars.outputs.verDebug }} | |
| verOldTag: ${{ steps.vars.outputs.verOldTag }} | |
| verTag: ${{ steps.vars.outputs.verTag }} | |
| verTitle: ${{ steps.vars.outputs.verTitle }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| architecture: x64 | |
| java-version: 8 | |
| - name: Setup PHP | |
| uses: shivammathur/setup-php@v2 | |
| with: | |
| php-version: '8.3' | |
| - name: Compute variables | |
| id: vars | |
| shell: pwsh | |
| run: | | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = 'Stop' | |
| # Ensure tags exist locally | |
| git fetch --tags --force | Out-Null | |
| $ref = "${env:GITHUB_REF}" # e.g. refs/tags/version1.2.3 or refs/heads/dev | |
| $eventType = "${env:GITHUB_EVENT_NAME}" # e.g. "push" or "pull_request" | |
| $isTag = $ref.StartsWith("refs/tags/") | |
| $isDev = ($ref -eq "refs/heads/dev") | |
| $isMaster = ($ref -eq "refs/heads/master") | |
| $isPush = ($eventType -eq "push") | |
| $H = (git rev-parse HEAD).Trim() | |
| function Set-Var([string]$name, [string]$value) { | |
| # For later steps in the SAME job | |
| "$name=$value" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append | |
| # For later jobs (job outputs) | |
| "$name=$value" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append | |
| } | |
| # Defaults | |
| Set-Var "doRelease" "false" | |
| Set-Var "verMajor" "" | |
| Set-Var "verMinor" "" | |
| Set-Var "verRelease" "" | |
| Set-Var "verBuild" "" | |
| Set-Var "verRevision" "" | |
| Set-Var "verLong" "" | |
| Set-Var "verRaw" "" | |
| Set-Var "verShort" "" | |
| Set-Var "verDebug" "" | |
| Set-Var "verOldTag" "" | |
| Set-Var "verTag" "" | |
| Set-Var "verTitle" "" | |
| $raw = ""; | |
| if ($isMaster) { | |
| $raw = php cicd_scripts/update_changelog.php true | |
| } | |
| if ($isDev -and $isPush) { | |
| $raw = php cicd_scripts/update_changelog.php false | |
| } | |
| if ($isMaster -or ($isDev -and $isPush)) { | |
| mkdir build/classes -Force | |
| javac -cp build/classes -d build/classes src/com/jpexs/build/ChangelogUpdater.java | |
| java -cp build/classes com.jpexs.build.ChangelogUpdater | |
| } | |
| if ($isMaster -and ($raw -match '^(\d+)\.(\d+)\.(\d+)$')) { | |
| $X = $Matches[1] | |
| $Y = $Matches[2] | |
| $Z = $Matches[3] | |
| Set-Var "verMajor" $X | |
| Set-Var "verMinor" $Y | |
| Set-Var "verRelease" $Z | |
| Set-Var "verBuild" "0" | |
| Set-Var "verRevision" $H | |
| Set-Var "verRaw" $raw | |
| Set-Var "verShort" $raw | |
| Set-Var "verLong" $raw | |
| Set-Var "verDebug" "false" | |
| Set-Var "verOldTag" "" | |
| Set-Var "verTag" "version$raw" | |
| Set-Var "doRelease" "true" | |
| Set-Var "verTitle" "version $raw" | |
| exit 0 | |
| } | |
| # Case 2: dev branch and push | |
| if ($isDev -and $isPush -and ($raw -eq "nightly")) { | |
| # Find latest nightlyN tag (max N) | |
| $nightlyTags = git tag --list 'nightly*' | |
| $maxN = -1 | |
| foreach ($t in $nightlyTags) { | |
| if ($t -match '^nightly(\d+)$') { | |
| $n = [int]$Matches[1] | |
| if ($n -gt $maxN) { $maxN = $n } | |
| } | |
| } | |
| if ($maxN -lt 0) { $maxN = 0 } # if none exists, start from 0 so M becomes 1 | |
| $M = $maxN + 1 | |
| # Find latest versionX.Y.Z tag by numeric comparison (major,minor,release) | |
| $versionTags = git tag --list 'version*' | |
| $best = $null | |
| foreach ($t in $versionTags) { | |
| if ($t -match '^version(\d+)\.(\d+)\.(\d+)$') { | |
| $maj = [int]$Matches[1] | |
| $min = [int]$Matches[2] | |
| $rel = [int]$Matches[3] | |
| $obj = [pscustomobject]@{ Tag=$t; Major=$maj; Minor=$min; Release=$rel } | |
| if (-not $best) { | |
| $best = $obj | |
| } else { | |
| if ($obj.Major -gt $best.Major -or | |
| ($obj.Major -eq $best.Major -and $obj.Minor -gt $best.Minor) -or | |
| ($obj.Major -eq $best.Major -and $obj.Minor -eq $best.Minor -and $obj.Release -gt $best.Release)) { | |
| $best = $obj | |
| } | |
| } | |
| } | |
| } | |
| if (-not $best) { | |
| throw "No versionX.Y.Z tag found. Create at least one version tag (e.g. version1.0.0)." | |
| } | |
| $X = $best.Major | |
| $Y = $best.Minor | |
| $Z = $best.Release | |
| Set-Var "verMajor" "$X" | |
| Set-Var "verMinor" "$Y" | |
| Set-Var "verRelease" "$Z" | |
| Set-Var "verBuild" "$M" | |
| Set-Var "verRevision" $H | |
| Set-Var "verLong" "$X.$Y.$Z nightly build $M" | |
| Set-Var "verRaw" "$X.$Y.$Z" | |
| Set-Var "verShort" "$X.$Y.$Z`_nightly$M" | |
| Set-Var "verDebug" "true" | |
| Set-Var "verOldTag" "nightly$maxN" | |
| Set-Var "verTag" "nightly$M" | |
| Set-Var "verTitle" "(PREVIEW) version $X.$Y.$Z nightly $M" | |
| Set-Var "doRelease" "true" | |
| exit 0 | |
| } | |
| # Other cases: doRelease stays false | |
| exit 0 | |
| - name: Prepare version info property file | |
| shell: pwsh | |
| run: | | |
| $VERSION_PROP_FILE = "version.properties" | |
| echo "">$VERSION_PROP_FILE | |
| echo "major=${{ steps.vars.outputs.verMajor }}">>$VERSION_PROP_FILE | |
| echo "minor=${{ steps.vars.outputs.verMinor }}">>$VERSION_PROP_FILE | |
| echo "release=${{ steps.vars.outputs.verRelease }}">>$VERSION_PROP_FILE | |
| echo "build=${{ steps.vars.outputs.verBuild }}">>$VERSION_PROP_FILE | |
| echo "revision=${{ steps.vars.outputs.verRevision }}">>$VERSION_PROP_FILE | |
| echo "debug=${{ steps.vars.outputs.verDebug }}">>$VERSION_PROP_FILE | |
| - name: Upload CHANGELOG.md artifact | |
| uses: actions/upload-artifact@v4 | |
| if: steps.vars.outputs.doRelease == 'true' | |
| with: | |
| name: changelog_md | |
| path: CHANGELOG.md | |
| - name: Upload version.properties artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: version_properties | |
| path: version.properties | |
| build: | |
| name: Build and test | |
| runs-on: windows-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| needs: compute-version | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v3 | |
| - name: Set up JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| architecture: x64 | |
| java-version: | | |
| 8 | |
| 21 | |
| - name: Set Java 8 | |
| shell: pwsh | |
| run: | | |
| echo "JAVA_HOME=$env:JAVA_HOME_8_X64" >> $env:GITHUB_ENV | |
| - name: Set up Ant | |
| run: choco install ant -y | |
| - name: Download version.properties artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: version_properties | |
| - name: Copy version.properties to lib | |
| run: copy version.properties libsrc/ffdec_lib/ | |
| - name: Check style | |
| run: ant checkstyle | |
| - name: Build and Test (Release) | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| run: ant new-version-set build test | |
| - name: Build and Test (Private) | |
| if: needs.compute-version.outputs.doRelease == 'false' | |
| run: ant build test | |
| - name: Set Java 21 | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| shell: pwsh | |
| run: | | |
| echo "JAVA_HOME=$env:JAVA_HOME_21_X64" >> $env:GITHUB_ENV | |
| - name: Javadoc | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| run: ant release_lib_javadoc | |
| - name: Upload lib javadoc artifact | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib_javadoc | |
| path: releases/ffdec_lib_javadoc_${{ needs.compute-version.outputs.verShort }}.zip | |
| - name: Upload dist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Upload lib dist | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: lib_dist | |
| path: libsrc/ffdec_lib/dist | |
| exe: | |
| name: Generate EXEs | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| needs: | |
| - compute-version | |
| - build | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v3 | |
| - name: Set up JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| architecture: x64 | |
| java-version: 8 | |
| # Wine must be used since Windows runner cannot run Resource hacker | |
| - name: Install Wine | |
| run: | | |
| sudo dpkg --add-architecture i386 | |
| sudo apt-get update -y -qq | |
| sudo apt-get install -y -qq wine | |
| # We need to add fake virtual desktop as Resource Hacker is not pure commandline app | |
| - name: Set up Xorg | |
| run: | | |
| sudo apt-get install -y -qq xorg xvfb xfonts-100dpi xfonts-75dpi xfonts-scalable xfonts-cyrillic | |
| - name: Install Resource Hacker | |
| env: | |
| RH_DIR: tools/wine/resourcehacker | |
| RH_ZIP: tools/wine/resourcehacker.zip | |
| RH_URL: https://www.free-decompiler.com/flash/tools/resource_hacker.zip | |
| #https://www.angusj.com/resourcehacker/resource_hacker.zip | |
| run: | | |
| set -euxo pipefail | |
| sudo apt-get install -y -qq unzip wget | |
| mkdir -p "$(dirname "$RH_ZIP")" | |
| mkdir -p "$RH_DIR" | |
| wget -q -O "$RH_ZIP" "$RH_URL" | |
| unzip -o "$RH_ZIP" -d "$RH_DIR" | |
| - name: Generate EXE splash screen | |
| run: | | |
| mkdir -p build/classes | |
| javac -d build/classes libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/BMPFile.java | |
| javac -cp build/classes -d build/classes src/com/jpexs/build/SplashScreenGenerator.java | |
| java -cp build/classes com.jpexs.build.SplashScreenGenerator "${{ needs.compute-version.outputs.verLong }}" | |
| - name: Replace EXE splash screen | |
| run: | | |
| export WINEPREFIX=$(pwd)/tools/wine | |
| cp resources/ffdec.exe $WINEPREFIX/ffdec.exe | |
| cp build/splash.bmp $WINEPREFIX/splash.bmp | |
| xvfb-run wine $WINEPREFIX/resourcehacker/ResourceHacker.exe -open $WINEPREFIX/ffdec.exe -save $WINEPREFIX/ffdec.exe -action addoverwrite -res $WINEPREFIX/splash.bmp -mask BITMAP,1 | |
| cp $WINEPREFIX/ffdec.exe resources/ffdec.exe | |
| - name: Generate EXE version info | |
| run: | | |
| sed -i \ | |
| -e 's/@MAJOR@/${{ needs.compute-version.outputs.verMajor }}/g' \ | |
| -e 's/@MINOR@/${{ needs.compute-version.outputs.verMinor }}/g' \ | |
| -e 's/@RELEASE@/${{ needs.compute-version.outputs.verRelease }}/g' \ | |
| -e 's/@BUILD@/${{ needs.compute-version.outputs.verBuild }}/g' \ | |
| -e 's/@VERSION@/${{ needs.compute-version.outputs.verShort }}/g' \ | |
| versioninfo.rc | |
| - name: Replace EXE version info | |
| run: | | |
| export WINEPREFIX=$(pwd)/tools/wine | |
| cp resources/ffdec.exe $WINEPREFIX/ffdec.exe | |
| cp versioninfo.rc $WINEPREFIX/versioninfo.rc | |
| xvfb-run wine $WINEPREFIX/resourcehacker/ResourceHacker.exe -open $WINEPREFIX/versioninfo.rc -save $WINEPREFIX/versioninfo.res -action compile | |
| xvfb-run wine $WINEPREFIX/resourcehacker/ResourceHacker.exe -open $WINEPREFIX/ffdec.exe -save $WINEPREFIX/ffdec.exe -action addoverwrite -res $WINEPREFIX/versioninfo.res -mask "Version Info,1" | |
| cp $WINEPREFIX/ffdec.exe resources/ffdec.exe | |
| - name: Upload EXE | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: unsigned_exe | |
| path: resources/ffdec.exe | |
| - name: Generate CLI EXE version info | |
| run: | | |
| sed -i \ | |
| -e 's/@MAJOR@/${{ needs.compute-version.outputs.verMajor }}/g' \ | |
| -e 's/@MINOR@/${{ needs.compute-version.outputs.verMinor }}/g' \ | |
| -e 's/@RELEASE@/${{ needs.compute-version.outputs.verRelease }}/g' \ | |
| -e 's/@BUILD@/${{ needs.compute-version.outputs.verBuild }}/g' \ | |
| -e 's/@VERSION@/${{ needs.compute-version.outputs.verShort }}/g' \ | |
| versioninfo-cli.rc | |
| - name: Replace CLI EXE version info | |
| run: | | |
| export WINEPREFIX=$(pwd)/tools/wine | |
| cp resources/ffdec-cli.exe $WINEPREFIX/ffdec-cli.exe | |
| cp versioninfo-cli.rc $WINEPREFIX/versioninfo-cli.rc | |
| xvfb-run wine $WINEPREFIX/resourcehacker/ResourceHacker.exe -open $WINEPREFIX/versioninfo-cli.rc -save $WINEPREFIX/versioninfo-cli.res -action compile | |
| xvfb-run wine $WINEPREFIX/resourcehacker/ResourceHacker.exe -open $WINEPREFIX/ffdec-cli.exe -save $WINEPREFIX/ffdec-cli.exe -action addoverwrite -res $WINEPREFIX/versioninfo-cli.res -mask "Version Info,1" | |
| cp $WINEPREFIX/ffdec-cli.exe resources/ffdec-cli.exe | |
| - name: Upload CLI EXE | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: unsigned_cli_exe | |
| path: resources/ffdec-cli.exe | |
| #--- Note: Windows runner cannot run Resource Hacker for some reason | |
| # exe: | |
| # name: Generate EXE | |
| # runs-on: windows-latest | |
| # needs: compute-version | |
| # if: needs.compute-version.outputs.doRelease == 'true' | |
| # steps: | |
| # - name: Checkout | |
| # uses: actions/checkout@v3 | |
| # - name: Set up JDK | |
| # uses: actions/setup-java@v4 | |
| # with: | |
| # distribution: adopt | |
| # architecture: x64 | |
| # java-version: 8 | |
| # | |
| # - name: Set up ResourceHacker | |
| # id: resource_hacker | |
| # shell: pwsh | |
| # run: | | |
| # $url = "https://www.angusj.com/resourcehacker/resource_hacker.zip" | |
| # $zip = "resource_hacker.zip" | |
| # $dest = "tools/resource_hacker" | |
| # | |
| # Invoke-WebRequest $url -OutFile $zip | |
| # Expand-Archive $zip -DestinationPath $dest -Force | |
| # $path = $dest + '/ResourceHacker.exe' | |
| # "path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
| # | |
| # - name: Generate EXE splash screen | |
| # shell: pwsh | |
| # run: | | |
| # mkdir build/classes | |
| # javac -d build/classes libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/BMPFile.java | |
| # javac -cp build/classes -d build/classes src/com/jpexs/build/SplashScreenGenerator.java | |
| # java -cp build/classes com.jpexs.build.SplashScreenGenerator "${{ needs.compute-version.outputs.verLong }}" | |
| # | |
| # - name: Replace EXE splash screen | |
| # shell: pwsh | |
| # run: | | |
| # $resource_hacker = "${{ steps.resource_hacker.outputs.path }}" | |
| # | |
| # & $resource_hacker -open resources/ffdec.exe -save resources/ffdec.exe -action addoverwrite -res build/splash.bmp -mask BITMAP,1 | |
| # - name: Generate EXE version info | |
| # shell: pwsh | |
| # run: | | |
| # $template = Get-Content -Path 'versioninfo.rc' -Raw -Encoding UTF8 | |
| # $t = $template | |
| # $t = $t -creplace '@MAJOR@', '${{ needs.compute-version.outputs.verMajor }}' | |
| # $t = $t -creplace '@MINOR@', '${{ needs.compute-version.outputs.verMinor }}' | |
| # $t = $t -creplace '@RELEASE@', '${{ needs.compute-version.outputs.verRelease }}' | |
| # $t = $t -creplace '@BUILD@', '${{ needs.compute-version.outputs.verBuild }}' | |
| # $t = $t -creplace '@VERSION@', '${{ needs.compute-version.outputs.verShort }}' | |
| # Set-Content -Path 'versioninfo.rc' -Value $t -Encoding UTF8 | |
| # - name: Replace EXE version info | |
| # shell: pwsh | |
| # run: | | |
| # $resource_hacker = "${{ steps.resource_hacker.outputs.path }}" | |
| # & $resource_hacker -open versioninfo.rc -save versioninfo.res -action compile | |
| # & $resource_hacker -open resources/ffdec.exe -save resources/ffdec.exe -action addoverwrite -res versioninfo.res -mask "Version Info,1" | |
| # - name: Upload EXE | |
| # uses: actions/upload-artifact@v4 | |
| # with: | |
| # name: unsigned_exe | |
| # path: resources/ffdec.exe | |
| sign_and_msi: | |
| name: Code signing, MSI installer | |
| runs-on: windows-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| needs: | |
| - compute-version | |
| - build | |
| - exe | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| env: | |
| GCP_PROJECT_ID: jpexs-ffdec | |
| GCP_LOCATION: europe | |
| KMS_KEYRING: jpexs-ffdec-keyring | |
| KMS_KEY: jpexs-ffdec-key2 | |
| KMS_KEY_VERSION: "1" | |
| CERT_PATH: "cert/user.crt" | |
| GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v4 | |
| - name: Download dist artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Download lib_dist artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib_dist | |
| path: libsrc/ffdec_lib/dist/ | |
| - name: Download unsigned EXE artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: unsigned_exe | |
| path: dist/ | |
| - name: Download unsigned CLI EXE artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: unsigned_cli_exe | |
| path: dist/ | |
| - name: Set up JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| architecture: x64 | |
| java-version: 23 | |
| - name: Build alt signer | |
| working-directory: altsigner | |
| run: mvn clean package | |
| - id: auth | |
| uses: google-github-actions/auth@v2 | |
| with: | |
| workload_identity_provider: "projects/541721778634/locations/global/workloadIdentityPools/github-pool/providers/github-provider" | |
| service_account: "gha-codesign@jpexs-ffdec.iam.gserviceaccount.com" | |
| - name: Setup gcloud | |
| uses: google-github-actions/setup-gcloud@v3 | |
| with: | |
| project_id: "${{ env.GCP_PROJECT_ID }}" | |
| - name: Install Google Cloud KMS CNG Provider | |
| shell: pwsh | |
| env: | |
| GH_TOKEN: ${{secrets.GH_TOKEN}} | |
| run: | | |
| $repo = "GoogleCloudPlatform/kms-integrations" | |
| $tmp = "$env:RUNNER_TEMP\kms" | |
| New-Item -ItemType Directory -Force -Path $tmp | Out-Null | |
| $tag = gh release list ` | |
| --repo $repo ` | |
| --limit 50 ` | |
| --json tagName,createdAt ` | |
| -q '[.[] | select(.tagName | startswith("cng-"))][0].tagName' | |
| if (-not $tag) { | |
| throw "No release found with tag cng-*" | |
| } | |
| Write-Host "Using release tag: $tag" | |
| gh release download $tag ` | |
| --repo $repo ` | |
| --pattern "*windows-amd64*.zip" ` | |
| --dir $tmp | |
| $zip = Get-ChildItem $tmp -Filter "*.zip" | Select-Object -First 1 | |
| if (-not $zip) { throw "ZIP asset not found (pattern *windows-amd64*.zip). Check names in releases." } | |
| $extract = Join-Path $tmp "extract" | |
| New-Item -ItemType Directory -Force -Path $extract | Out-Null | |
| Expand-Archive -Path $zip.FullName -DestinationPath $extract -Force | |
| $msi = Get-ChildItem $extract -Recurse -Filter "*.msi" | Select-Object -First 1 | |
| if (-not $msi) { throw "MSI not found inside ZIP. Check structure of archive in releases." } | |
| Write-Host "Installing: $($msi.FullName)" | |
| Start-Process msiexec.exe -Wait -ArgumentList "/i `"$($msi.FullName)`" /qn /norestart" | |
| - name: Sign ffdec.jar | |
| shell: pwsh | |
| run: | | |
| $kc = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_LOCATION/keyRings/$env:KMS_KEYRING/cryptoKeys/$env:KMS_KEY/cryptoKeyVersions/$env:KMS_KEY_VERSION" | |
| java -cp altsigner\target\kms-jarsigner-1.0.jar com.jpexs.kmsjarsigner.SignJar dist/ffdec.jar dist/ffdec-signed.jar cert/cert-chain.pem $kc http://timestamp.sectigo.com | |
| move dist/ffdec-signed.jar dist/ffdec.jar -Force | |
| - name: Verify ffdec.jar signature | |
| shell: pwsh | |
| run: jarsigner.exe -verify -strict dist/ffdec.jar | |
| - name: Upload signed JAR artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: signed_jar | |
| path: dist/ffdec.jar | |
| - name: Sign ffdec_lib.jar | |
| shell: pwsh | |
| run: | | |
| $kc = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_LOCATION/keyRings/$env:KMS_KEYRING/cryptoKeys/$env:KMS_KEY/cryptoKeyVersions/$env:KMS_KEY_VERSION" | |
| java -cp altsigner\target\kms-jarsigner-1.0.jar com.jpexs.kmsjarsigner.SignJar libsrc/ffdec_lib/dist/ffdec_lib.jar libsrc/ffdec_lib/dist/ffdec_lib-signed.jar cert/cert-chain.pem $kc http://timestamp.sectigo.com | |
| move libsrc/ffdec_lib/dist/ffdec_lib-signed.jar libsrc/ffdec_lib/dist/ffdec_lib.jar -Force | |
| - name: Verify ffdec_lib.jar signature | |
| shell: pwsh | |
| run: jarsigner.exe -verify -strict libsrc/ffdec_lib/dist/ffdec_lib.jar | |
| - name: Upload signed lib JAR artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: signed_lib_jar | |
| path: libsrc/ffdec_lib/dist/ffdec_lib.jar | |
| - name: Locate signtool | |
| id: signtool | |
| shell: pwsh | |
| run: | | |
| $candidates = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin" ` | |
| -Recurse -Filter signtool.exe -ErrorAction SilentlyContinue | |
| Write-Host "All signtool candidates:" | |
| $candidates | ForEach-Object { | |
| Write-Host " - $($_.FullName)" | |
| } | |
| # vyber jen x64 | |
| $x64 = $candidates | Where-Object { | |
| $_.FullName -match "\\x64\\" | |
| } | |
| if (-not $x64) { | |
| throw "No x64 signtool.exe found" | |
| } | |
| $path = $x64 | Sort-Object FullName -Descending | Select-Object -First 1 | |
| "path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
| - name: Sign EXE with KMS key | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| $kc = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_LOCATION/keyRings/$env:KMS_KEYRING/cryptoKeys/$env:KMS_KEY/cryptoKeyVersions/$env:KMS_KEY_VERSION" | |
| $ErrorActionPreference = 'Stop' | |
| $exe = $signtool | |
| $args = @( | |
| "sign", | |
| "/v", | |
| "/debug", | |
| "/fd", "sha256", | |
| "/tr", "http://timestamp.sectigo.com?td=sha256", | |
| "/td", "sha256", | |
| "/f", "$env:CERT_PATH", | |
| "/csp", "Google Cloud KMS Provider", | |
| "/kc", "$kc", | |
| "dist/ffdec.exe" | |
| ) | |
| # --- retry policy --- | |
| $maxAttempts = 5 | |
| $delaySeconds = 10 | |
| $needle = "SignTool Error: An unexpected internal error has occurred" | |
| for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { | |
| Write-Host "Attempt $attempt/${maxAttempts}: $exe $($args -join ' ')" | |
| $output = & $exe @args 2>&1 | Out-String | |
| $exitCode = $LASTEXITCODE | |
| if ($output) { Write-Host $output.TrimEnd() } | |
| if ($exitCode -eq 0) { | |
| Write-Host "Succeeded." | |
| exit 0 | |
| } | |
| $hasNeedle = $output -match [regex]::Escape($needle) | |
| if ($hasNeedle -and $attempt -lt $maxAttempts) { | |
| Write-Warning "Detected transient SignTool internal error. Retrying in $delaySeconds seconds..." | |
| Start-Sleep -Seconds $delaySeconds | |
| continue | |
| } | |
| if ($hasNeedle) { | |
| throw "Failed after $maxAttempts attempts due to repeated SignTool internal error (exit code $exitCode)." | |
| } else { | |
| throw "Command failed (exit code $exitCode). Output did not match retry condition." | |
| } | |
| } | |
| - name: Verify EXE signature | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| & $signtool verify /pa /v "dist/ffdec.exe" | |
| - name: Sign CLI EXE with KMS key | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| $kc = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_LOCATION/keyRings/$env:KMS_KEYRING/cryptoKeys/$env:KMS_KEY/cryptoKeyVersions/$env:KMS_KEY_VERSION" | |
| $ErrorActionPreference = 'Stop' | |
| $exe = $signtool | |
| $args = @( | |
| "sign", | |
| "/v", | |
| "/debug", | |
| "/fd", "sha256", | |
| "/tr", "http://timestamp.sectigo.com?td=sha256", | |
| "/td", "sha256", | |
| "/f", "$env:CERT_PATH", | |
| "/csp", "Google Cloud KMS Provider", | |
| "/kc", "$kc", | |
| "dist/ffdec-cli.exe" | |
| ) | |
| # --- retry policy --- | |
| $maxAttempts = 5 | |
| $delaySeconds = 10 | |
| $needle = "SignTool Error: An unexpected internal error has occurred" | |
| for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { | |
| Write-Host "Attempt $attempt/${maxAttempts}: $exe $($args -join ' ')" | |
| $output = & $exe @args 2>&1 | Out-String | |
| $exitCode = $LASTEXITCODE | |
| if ($output) { Write-Host $output.TrimEnd() } | |
| if ($exitCode -eq 0) { | |
| Write-Host "Succeeded." | |
| exit 0 | |
| } | |
| $hasNeedle = $output -match [regex]::Escape($needle) | |
| if ($hasNeedle -and $attempt -lt $maxAttempts) { | |
| Write-Warning "Detected transient SignTool internal error. Retrying in $delaySeconds seconds..." | |
| Start-Sleep -Seconds $delaySeconds | |
| continue | |
| } | |
| if ($hasNeedle) { | |
| throw "Failed after $maxAttempts attempts due to repeated SignTool internal error (exit code $exitCode)." | |
| } else { | |
| throw "Command failed (exit code $exitCode). Output did not match retry condition." | |
| } | |
| } | |
| - name: Verify CLI EXE signature | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| & $signtool verify /pa /v "dist/ffdec-cli.exe" | |
| - name: Get Msi tools path | |
| id: msitools | |
| shell: pwsh | |
| run: | | |
| $candidates = Get-ChildItem "C:\Program Files (x86)\Windows Kits\10\bin" ` | |
| -Recurse -Filter MsiTran.exe -ErrorAction SilentlyContinue | |
| Write-Host "All signtool candidates:" | |
| $candidates | ForEach-Object { | |
| Write-Host " - $($_.FullName)" | |
| } | |
| $x86 = $candidates | Where-Object { | |
| $_.FullName -match "\\x86\\" | |
| } | |
| if (-not $x86) { | |
| throw "No x86 MsiTran.exe found" | |
| } | |
| $path = $x86 | Sort-Object FullName -Descending | Select-Object -First 1 | |
| $path = Split-Path $path -Parent | |
| "path=$path" | Out-File -FilePath $env:GITHUB_OUTPUT -Append | |
| #Add-Content $env:GITHUB_PATH $path | |
| - name: Inject version info | |
| shell: pwsh | |
| run: | | |
| $template = Get-Content -Path 'wix\Product.wxs' -Raw -Encoding UTF8 | |
| $t = $template | |
| $t = $t -creplace 'Name="JPEXS Free Flash Decompiler 1.0.0"', 'Name="JPEXS Free Flash Decompiler ${{ needs.compute-version.outputs.verLong }}"' | |
| $t = $t -creplace 'Version="1.0.0"', 'Version="${{ needs.compute-version.outputs.verRaw }}"' | |
| $t = $t -creplace 'Id="ARPVERSION" Value="1.0.0"', 'Id="ARPVERSION" Value="${{ needs.compute-version.outputs.verLong }}"' | |
| Set-Content -Path 'wix\Product.wxs' -Value $t -Encoding UTF8 | |
| - name: Create installer | |
| shell: cmd | |
| working-directory: wix | |
| run: | | |
| set MsiToolsPath=${{ steps.msitools.outputs.path }} | |
| .\Build_Release.cmd | |
| - name: Sign MSI with KMS key | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| $kc = "projects/$env:GCP_PROJECT_ID/locations/$env:GCP_LOCATION/keyRings/$env:KMS_KEYRING/cryptoKeys/$env:KMS_KEY/cryptoKeyVersions/$env:KMS_KEY_VERSION" | |
| $ErrorActionPreference = 'Stop' | |
| $exe = $signtool | |
| $args = @( | |
| "sign", | |
| "/v", | |
| "/debug", | |
| "/fd", "sha256", | |
| "/tr", "http://timestamp.sectigo.com?td=sha256", | |
| "/td", "sha256", | |
| "/f", "$env:CERT_PATH", | |
| "/csp", "Google Cloud KMS Provider", | |
| "/kc", "$kc", | |
| "wix/bin/Release/FFDec.msi" | |
| ) | |
| # --- retry policy --- | |
| $maxAttempts = 5 | |
| $delaySeconds = 10 | |
| $needle = "SignTool Error: An unexpected internal error has occurred" | |
| for ($attempt = 1; $attempt -le $maxAttempts; $attempt++) { | |
| Write-Host "Attempt $attempt/${maxAttempts}: $exe $($args -join ' ')" | |
| $output = & $exe @args 2>&1 | Out-String | |
| $exitCode = $LASTEXITCODE | |
| if ($output) { Write-Host $output.TrimEnd() } | |
| if ($exitCode -eq 0) { | |
| Write-Host "Succeeded." | |
| exit 0 | |
| } | |
| $hasNeedle = $output -match [regex]::Escape($needle) | |
| if ($hasNeedle -and $attempt -lt $maxAttempts) { | |
| Write-Warning "Detected transient SignTool internal error. Retrying in $delaySeconds seconds..." | |
| Start-Sleep -Seconds $delaySeconds | |
| continue | |
| } | |
| if ($hasNeedle) { | |
| throw "Failed after $maxAttempts attempts due to repeated SignTool internal error (exit code $exitCode)." | |
| } else { | |
| throw "Command failed (exit code $exitCode). Output did not match retry condition." | |
| } | |
| } | |
| - name: Verify MSI signature | |
| shell: pwsh | |
| run: | | |
| $signtool = "${{ steps.signtool.outputs.path }}" | |
| & $signtool verify /pa /v "wix/bin/Release/FFDec.msi" | |
| - name: Upload signed EXE artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: signed_exe | |
| path: dist/ffdec.exe | |
| - name: Upload signed CLI EXE artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: signed_cli_exe | |
| path: dist/ffdec-cli.exe | |
| - name: Rename MSI | |
| shell: cmd | |
| run: | | |
| mkdir releases | |
| move wix\bin\Release\FFDec.msi releases\ffdec_${{ needs.compute-version.outputs.verShort }}.msi | |
| - name: Upload signed MSI artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: signed_msi | |
| path: releases/ffdec_${{ needs.compute-version.outputs.verShort }}.msi | |
| packages: | |
| name: Create packages | |
| runs-on: ubuntu-latest | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| needs: | |
| - compute-version | |
| - build | |
| - exe | |
| - sign_and_msi | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v3 | |
| - name: Download dist artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dist | |
| path: dist/ | |
| - name: Download signed jar artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: signed_jar | |
| path: dist/ | |
| - name: Download lib dist artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib_dist | |
| path: libsrc/ffdec_lib/dist/ | |
| - name: Download signed lib jar artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: signed_lib_jar | |
| path: libsrc/ffdec_lib/dist/ | |
| - name: Copy signed ffdec_lib.jar to dist/lib dir | |
| run: cp libsrc/ffdec_lib/dist/ffdec_lib.jar dist/lib/ffdec_lib.jar | |
| - name: Download signed EXE artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: signed_exe | |
| path: dist/ | |
| - name: Download signed CLI EXE artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: signed_cli_exe | |
| path: dist/ | |
| - name: Download signed MSI artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: signed_msi | |
| path: releases/ | |
| - name: Set up JDK | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: adopt | |
| architecture: x64 | |
| java-version: 8 | |
| - name: Set up Ant | |
| run: | | |
| sudo apt-get update -y -qq | |
| sudo apt-get install -y -qq ant | |
| - name: Download CHANGELOG.md artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: changelog_md | |
| - name: Download version.properties artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: version_properties | |
| - name: Copy version.properties to lib | |
| run: cp version.properties libsrc/ffdec_lib/ | |
| - name: Update Dockerfile | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| run: | | |
| sed -E -i 's|version[^/]+/ffdec_[^/]+\.zip|version${{needs.compute-version.outputs.verRaw}}/ffdec_${{needs.compute-version.outputs.verRaw}}.zip|g' Dockerfile | |
| - name: Upload Dockerfile | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: dockerfile | |
| path: Dockerfile | |
| - name: Update metainfo | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| run: | | |
| mkdir -p build/classes | |
| javac -cp build/classes -d build/classes src/com/jpexs/build/MetainfoUpdater.java | |
| java -cp build/classes com.jpexs.build.MetainfoUpdater | |
| - name: Upload metainfo | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: metainfo | |
| path: resources/com.jpexs.decompiler.flash.metainfo.xml | |
| - name: Create packages | |
| run: ant new-version-set release-no-dist | |
| - name: Upload packages | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: packages | |
| path: releases | |
| deploy: | |
| name: Deploy to GitHub | |
| runs-on: ubuntu-latest | |
| if: needs.compute-version.outputs.doRelease == 'true' | |
| # This one is different from others | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: false | |
| needs: | |
| - compute-version | |
| - packages | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v3 | |
| - name: Set up PHP | |
| run: | | |
| sudo apt-get update -y -qq | |
| sudo apt-get install -y -qq php | |
| - name: Download packages artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: packages | |
| path: releases/ | |
| - name: Download lib javadoc artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: lib_javadoc | |
| path: releases/ | |
| - name: Download CHANGELOG.md artifact | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: changelog_md | |
| - name: Generate nightly release description | |
| if: needs.compute-version.outputs.verDebug == 'true' | |
| run: php cicd_scripts/format_release_info.php -filever "${{ needs.compute-version.outputs.verShort }}" Unreleased ${{ needs.compute-version.outputs.verTag }} ./CHANGELOG.md "${{ env.CICD_REPO_SLUG }}" > ./release_notes.md | |
| - name: Generate release description | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| run: php cicd_scripts/format_release_info.php -filever "${{ needs.compute-version.outputs.verShort }}" "${{ needs.compute-version.outputs.verShort }}" ${{ needs.compute-version.outputs.verTag }} ./CHANGELOG.md "${{ env.CICD_REPO_SLUG }}" > ./release_notes.md | |
| - name: Download Dockerfile artifact | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: dockerfile | |
| - name: Download metainfo artifact | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| uses: actions/download-artifact@v4 | |
| with: | |
| name: metainfo | |
| path: resources/ | |
| - name: Commit CHANGELOG, metainfo, Dockerfile | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| run: | | |
| git add CHANGELOG.md | |
| git add Dockerfile | |
| git add resources/com.jpexs.decompiler.flash.metainfo.xml | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git commit -m "chore: change version to ${{ needs.compute-version.outputs.verRaw }}" -m "[ci skip]" | |
| git push origin master | |
| - name: Upload release notes artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release_notes | |
| path: ./release_notes.md | |
| - name: Create tag | |
| run: | | |
| TAG="${{ needs.compute-version.outputs.verTag }}" | |
| git fetch --tags --force | |
| if git rev-parse "$TAG" >/dev/null 2>&1; then | |
| echo "Tag $TAG already exists -> skipping tag creation." | |
| exit 0 | |
| fi | |
| git config user.name "github-actions[bot]" | |
| git config user.email "github-actions[bot]@users.noreply.github.com" | |
| git tag "$TAG" | |
| git push origin "$TAG" | |
| - name: Create GitHub Release + upload assets | |
| uses: softprops/action-gh-release@v2 | |
| with: | |
| tag_name: ${{ needs.compute-version.outputs.verTag }} | |
| name: ${{ needs.compute-version.outputs.verTitle }} | |
| body_path: ./release_notes.md | |
| preserve_order: true | |
| prerelease: ${{ needs.compute-version.outputs.verDebug == 'true'}} | |
| fail_on_unmatched_files: true | |
| files: | | |
| releases/ffdec_${{ needs.compute-version.outputs.verShort }}.msi | |
| releases/ffdec_${{ needs.compute-version.outputs.verShort }}.zip | |
| releases/ffdec_${{ needs.compute-version.outputs.verShort }}.deb | |
| releases/ffdec_${{ needs.compute-version.outputs.verShort }}.pkg | |
| releases/ffdec_${{ needs.compute-version.outputs.verShort }}_macosx.zip | |
| releases/ffdec_lib_${{ needs.compute-version.outputs.verShort }}.zip | |
| releases/ffdec_lib_javadoc_${{ needs.compute-version.outputs.verShort }}.zip | |
| - name: Remove old nightly | |
| if: needs.compute-version.outputs.verDebug == 'true' | |
| env: | |
| GH_TOKEN: ${{ github.token }} | |
| run: | | |
| gh release delete ${{needs.compute-version.outputs.verOldTag}} --yes --cleanup-tag | |
| - name: Upload to Nexus Mods | |
| if: needs.compute-version.outputs.verDebug == 'false' | |
| uses: Nexus-Mods/upload-action@v1.0.0-beta.3 | |
| with: | |
| api_key: ${{ secrets.NEXUSMODS_API_KEY }} | |
| file_group_id: 7255064 | |
| filename: "releases/ffdec_${{ needs.compute-version.outputs.verShort }}.zip" | |
| version: ${{ needs.compute-version.outputs.verShort }} | |
| display_name: "FFDec - Zipped" | |
| file_category: main |