From 20fb89a66c065e0dde7ac2e8c09183b90d843cc5 Mon Sep 17 00:00:00 2001 From: Nando Vieira Date: Tue, 12 Nov 2024 14:04:17 -0800 Subject: [PATCH] Generate windows installer. --- .github/workflows/binaries.yml | 59 ++++++++++++++++++++++++++++++ installer.nsi | 64 +++++++++++++++++++++++++++++++++ stellar.ico | Bin 0 -> 12418 bytes 3 files changed, 123 insertions(+) create mode 100644 installer.nsi create mode 100644 stellar.ico diff --git a/.github/workflows/binaries.yml b/.github/workflows/binaries.yml index 25cea73668..9829c75602 100644 --- a/.github/workflows/binaries.yml +++ b/.github/workflows/binaries.yml @@ -44,41 +44,50 @@ jobs: - uses: actions/checkout@v4 - run: rustup update - run: rustup target add ${{ matrix.sys.target }} + - if: matrix.sys.target == 'aarch64-unknown-linux-gnu' run: sudo apt-get update && sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu libudev-dev + - name: Setup vars run: | version="$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "stellar-cli") | .version')" echo "VERSION=${version}" >> $GITHUB_ENV echo "NAME=${{ matrix.crate.name }}-${version}-${{ matrix.sys.target }}" >> $GITHUB_ENV + - name: Package (release only) if: github.event_name == 'release' run: cargo package --no-verify --package ${{ matrix.crate.name }} + - name: Package Extract (release only) if: github.event_name == 'release' run: | cd target/package tar xvfz ${{ matrix.crate.name }}-$VERSION.crate echo "BUILD_WORKING_DIR=target/package/${{ matrix.crate.name }}-$VERSION" >> $GITHUB_ENV + - name: Build env: CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc working-directory: ${{ env.BUILD_WORKING_DIR }} run: cargo build --target-dir="$GITHUB_WORKSPACE/target" --package ${{ matrix.crate.name }} --features opt --release --target ${{ matrix.sys.target }} + - name: Build provenance for attestation (release only) if: github.event_name == 'release' uses: actions/attest-build-provenance@v1 with: subject-path: target/${{ matrix.sys.target }}/release/${{ matrix.crate.binary }}${{ matrix.sys.ext }} + - name: Compress run: | cd target/${{ matrix.sys.target }}/release tar czvf $NAME.tar.gz ${{ matrix.crate.binary }}${{ matrix.sys.ext }} + - name: Upload to Artifacts uses: actions/upload-artifact@v4 with: name: ${{ env.NAME }} path: 'target/${{ matrix.sys.target }}/release/${{ env.NAME }}.tar.gz' + - name: Upload to Release (release only) if: github.event_name == 'release' uses: actions/github-script@v7 @@ -92,3 +101,53 @@ jobs: name: '${{ env.NAME }}.tar.gz', data: fs.readFileSync('target/${{ matrix.sys.target }}/release/${{ env.NAME }}.tar.gz'), }); + + installer: + needs: build + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install Dependencies + run: sudo apt-get update && sudo apt-get -y install nsis wget + + - name: Setup vars + run: | + version="$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "stellar-cli") | .version')" + echo "VERSION=${version}" >> $GITHUB_ENV + echo "STELLAR_CLI_INSTALLER=stellar-cli-installer-${{ env.VERSION }}-x86_64-pc-windows-msvc.exe" + + - name: Download Artifacts + uses: actions/download-artifact@v4 + with: + name: stellar-cli-${{ inputs.version }}-x86_64-pc-windows-msvc.tar.gz + path: stellar-cli.tar.gz + + - name: Uncompress Artifact + run: tar xvf stellar-cli.tar.gz + + - name: Build Installer + run: | + makensis -V4 -DSTELLAR_CLI_INSTALLER="${{ env.STELLAR_CLI_INSTALLER }}" -DSTELLAR_CLI_VERSION="${{ env.VERSION }}" installer.nsi + + - name: Build provenance for attestation (release only) + if: github.event_name == 'release' + uses: actions/attest-build-provenance@v1 + with: + subject-path: ${{ env.STELLAR_CLI_INSTALLER }} + + - name: Upload to Release (release only) + if: github.event_name == 'release' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + await github.rest.repos.uploadReleaseAsset({ + owner: context.repo.owner, + repo: context.repo.repo, + release_id: ${{ github.event.release.id }}, + name: '${{ env.STELLAR_CLI_INSTALLER }}', + data: fs.readFileSync('${{ env.STELLAR_CLI_INSTALLER }}'), + }); + diff --git a/installer.nsi b/installer.nsi new file mode 100644 index 0000000000..95c2fb17b5 --- /dev/null +++ b/installer.nsi @@ -0,0 +1,64 @@ +OutFile "${STELLAR_CLI_INSTALLER}" +InstallDir "$PROGRAMFILES\Stellar CLI" +RequestExecutionLevel admin + +; Define WM_SETTINGCHANGE since NSIS doesn’t natively recognize it +!define WM_SETTINGCHANGE 0x1A + +Section "Install" + SetOutPath "$INSTDIR" + File "stellar.exe" + File "stellar.ico" + WriteUninstaller "$INSTDIR\Uninstall.exe" + + ; Create a shortcut in the Start Menu + CreateDirectory "$SMPROGRAMS\Stellar CLI" + CreateShortCut "$SMPROGRAMS\Stellar CLI\Uninstall.lnk" "$INSTDIR\Uninstall.exe" "" "$INSTDIR\Uninstall.exe" 0 + + ; Add an entry to the Windows "Programs and Features" list + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "DisplayName" "Stellar CLI" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "UninstallString" "$INSTDIR\Uninstall.exe" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "DisplayIcon" "$INSTDIR\stellar.ico" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "DisplayVersion" "${STELLAR_CLI_VERSION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "Publisher" "Stellar" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" "InstallLocation" "$INSTDIR" + + ; Add install directory to the PATH + ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" + StrCpy $1 "$0;$INSTDIR" + WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$1" + + ; Notify Windows that the PATH has changed + System::Call 'user32::SendMessageA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, i 0)' +SectionEnd + +Section "Uninstall" + Delete "$INSTDIR\stellar.exe" + Delete "$INSTDIR\Uninstall.exe" + RMDir "$INSTDIR" + + ; Remove the Start Menu shortcut + Delete "$SMPROGRAMS\Stellar CLI\Uninstall.lnk" + RMDir "$SMPROGRAMS\Stellar CLI" + + ; Remove the entry from "Programs and Features" + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\Stellar CLI" + + ; Restore PATH without the installation directory + ReadRegStr $0 HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" + StrCpy $1 "$0" ; Store the original PATH in $1 + + ; Remove install directory from PATH (manual string removal) + StrLen $2 "$INSTDIR" + loop: + StrCpy $3 "$1" "$2" + StrCmp $3 "$INSTDIR" 0 +3 + StrCpy $1 "$1" "" $2 + goto loop + + ; Write the modified PATH back to registry + WriteRegStr HKLM "SYSTEM\CurrentControlSet\Control\Session Manager\Environment" "Path" "$1" + + ; Notify Windows that the PATH has changed + System::Call 'user32::SendMessageA(i 0xFFFF, i ${WM_SETTINGCHANGE}, i 0, i 0)' +SectionEnd diff --git a/stellar.ico b/stellar.ico new file mode 100644 index 0000000000000000000000000000000000000000..44129184b4441aa6e8a1195164d24f247f699581 GIT binary patch literal 12418 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 Zk`Td(+;VCv{9gnpHKm)FPYPxM{|7p)hBE*F literal 0 HcmV?d00001