diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d2ba698..d29611f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,7 +2,9 @@ name: Run tests on: push: + paths-ignore: ["**.md", LICENSE] pull_request: + paths-ignore: ["**.md", LICENSE] workflow_dispatch: jobs: @@ -12,10 +14,11 @@ jobs: strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] variant: [default, large-strings, advanced-logging] steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - name: Setup NSIS id: nsis @@ -37,10 +40,8 @@ jobs: [ "$OUT_NSISDIR" = "$NSISDIR" ] [ -f "$NSISDIR/Include/MUI2.nsh" ] - # makensis must come from PATH, i.e. the action put $PREFIX/bin there - makensis -VERSION + # Unqualified: proves the action put the bin dir on PATH info=$(makensis -HDRINFO) - echo "$info" strlen=8192 [ "$LARGE" = "true" ] || strlen=1024 @@ -66,13 +67,34 @@ jobs: makensis test.nsi [ -f test.exe ] + windows-combo-rejected: + runs-on: windows-latest + steps: + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Setup NSIS with both special builds + id: nsis + continue-on-error: true + uses: ./ + with: + large-strings: true + advanced-logging: true + + - name: Check the step failed + shell: bash + run: '[ "${{ steps.nsis.outcome }}" = failure ]' + pinned-version: runs-on: ubuntu-latest steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - id: nsis + - name: Checkout + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + - name: Setup NSIS + id: nsis uses: ./ with: version: "3.10" - - shell: bash + + - name: Check the pinned version was used + shell: bash run: '[ "${{ steps.nsis.outputs.version }}" = "3.10" ] && makensis -VERSION | grep -q 3.10' diff --git a/README.md b/README.md index c8f2fb4..6a16816 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,6 @@ Set up [NSIS](https://nsis.sourceforge.io/) in your GitHub workflow. -> [!WARNING] -> This action currently only supports Linux and macOS runners. - ## Usage ```yaml @@ -31,8 +28,13 @@ With build options: | Name | Default | Description | | ------------------ | -------- | ------------------------------------------------------------- | | `version` | `latest` | NSIS version, e.g. `3.12`. `latest` resolves via SourceForge. | -| `large-strings` | `false` | Build with `NSIS_MAX_STRLEN=8192`. | -| `advanced-logging` | `false` | Build with `NSIS_CONFIG_LOG=yes`. | +| `large-strings` | `false` | `NSIS_MAX_STRLEN=8192`. | +| `advanced-logging` | `false` | `NSIS_CONFIG_LOG=yes`. | + +> [!NOTE] +> On Windows, `large-strings` and `advanced-logging` cannot be combined: the +> action uses upstream's prebuilt special builds and there is no build that +> ships both. Enabling both fails the step. ## Outputs @@ -41,8 +43,9 @@ With build options: | `version` | Resolved NSIS version. | | `nsisdir` | NSIS installation directory (also exported as `NSISDIR`). | -Builds are cached per OS, version and option combination, so only the first run -pays the compile cost. +On Linux and macOS, NSIS is built from source; on Windows the action installs +upstream's prebuilt binaries. Either way the result is cached per OS, version +and option combination, so only the first run pays the setup cost. ## License diff --git a/action.yml b/action.yml index af3ee53..107dff8 100644 --- a/action.yml +++ b/action.yml @@ -1,15 +1,15 @@ name: Setup NSIS -description: Build NSIS from source on Linux and macOS and expose it via NSISDIR +description: Set up NSIS on Linux, macOS and Windows and expose it via NSISDIR inputs: version: description: NSIS version, e.g. 3.12, or "latest" default: latest large-strings: - description: Build with NSIS_MAX_STRLEN=8192 + description: NSIS_MAX_STRLEN=8192 default: "false" advanced-logging: - description: Build with NSIS_CONFIG_LOG=yes + description: NSIS_CONFIG_LOG=yes default: "false" outputs: @@ -18,7 +18,7 @@ outputs: value: ${{ steps.vars.outputs.version }} nsisdir: description: NSIS installation directory - value: ${{ steps.vars.outputs.prefix }}/share/nsis + value: ${{ steps.vars.outputs.nsisdir }} runs: using: composite @@ -32,6 +32,7 @@ runs: LOG: ${{ inputs.advanced-logging }} run: | set -euo pipefail + if [ "$VERSION" = latest ]; then # SourceForge has no "latest file" URL; its release JSON names the current one VERSION=$(curl -fsSL "https://sourceforge.net/projects/nsis/best_release.json" \ @@ -39,9 +40,30 @@ runs: [ -n "$VERSION" ] || { echo "could not resolve latest NSIS version"; exit 1; } echo "resolved latest NSIS version: $VERSION" fi + + if [ "${{ runner.os }}" = Windows ]; then + # Windows uses upstream's prebuilt binaries, and there is no build that + # combines both special builds + if [ "$LARGE" = "true" ] && [ "$LOG" = "true" ]; then + echo "large-strings and advanced-logging cannot be combined on Windows" >&2 + exit 1 + fi + + # Forward slashes: usable from bash and from PATH alike + prefix=$(cygpath -m "$HOME/nsis") + nsisdir=$prefix + bindir=$prefix + else + prefix=$HOME/nsis + nsisdir=$prefix/share/nsis + bindir=$prefix/bin + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" - echo "prefix=$HOME/nsis" >> "$GITHUB_OUTPUT" - echo "key=nsis-${{ runner.os }}-$VERSION-ls$LARGE-al$LOG" >> "$GITHUB_OUTPUT" + echo "prefix=$prefix" >> "$GITHUB_OUTPUT" + echo "nsisdir=$nsisdir" >> "$GITHUB_OUTPUT" + echo "bindir=$bindir" >> "$GITHUB_OUTPUT" + echo "key=nsis-${{ runner.os }}-$VERSION-largeStrings=$LARGE-advancedLogging=$LOG" >> "$GITHUB_OUTPUT" - name: Restore cached NSIS build id: cache @@ -50,6 +72,36 @@ runs: path: ~/nsis key: ${{ steps.vars.outputs.key }} + # Upstream ships prebuilt Windows binaries, including for both special builds, + # so there is nothing to compile here + - name: Install NSIS (Windows) + if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Windows' + shell: bash + working-directory: ${{ runner.temp }} + env: + VERSION: ${{ steps.vars.outputs.version }} + LARGE: ${{ inputs.large-strings }} + LOG: ${{ inputs.advanced-logging }} + PREFIX: ${{ steps.vars.outputs.prefix }} + run: | + set -euo pipefail + base="https://downloads.sourceforge.net/project/nsis/NSIS%20${VERSION%%.*}/$VERSION" + curl -fsSLO "$base/nsis-$VERSION.zip" + 7z x -y -bso0 "nsis-$VERSION.zip" + + mkdir -p "$PREFIX" + cp -R "nsis-$VERSION/." "$PREFIX/" + + # Special builds are overlays: makensis.exe plus matching stubs, no top-level dir + variant="" + [ "$LARGE" = "true" ] && variant="strlen_8192" + [ "$LOG" = "true" ] && variant="log" + + if [ -n "$variant" ]; then + curl -fsSLO "$base/nsis-$VERSION-$variant.zip" + 7z x -y -bso0 -o"$PREFIX" "nsis-$VERSION-$variant.zip" + fi + - name: Install build dependencies (Linux) if: steps.cache.outputs.cache-hit != 'true' && runner.os == 'Linux' shell: bash @@ -67,7 +119,7 @@ runs: brew install scons mingw-w64 - name: Download and build NSIS - if: steps.cache.outputs.cache-hit != 'true' + if: steps.cache.outputs.cache-hit != 'true' && runner.os != 'Windows' shell: bash working-directory: ${{ runner.temp }} env: @@ -98,6 +150,7 @@ runs: STRIP=0 VERSION="$VERSION" ) + [ "$LARGE" = "true" ] && args+=(NSIS_MAX_STRLEN=8192) [ "$LOG" = "true" ] && args+=(NSIS_CONFIG_LOG=yes) @@ -108,12 +161,12 @@ runs: - name: Export NSISDIR and verify shell: bash env: - PREFIX: ${{ steps.vars.outputs.prefix }} + NSISDIR: ${{ steps.vars.outputs.nsisdir }} + BINDIR: ${{ steps.vars.outputs.bindir }} run: | set -euo pipefail - echo "NSISDIR=$PREFIX/share/nsis" >> "$GITHUB_ENV" - echo "$PREFIX/bin" >> "$GITHUB_PATH" - export NSISDIR="$PREFIX/share/nsis" - echo "makensis v$("$PREFIX/bin/makensis" -VERSION)" + echo "NSISDIR=$NSISDIR" >> "$GITHUB_ENV" + echo "$BINDIR" >> "$GITHUB_PATH" + echo "makensis $("$BINDIR/makensis" -VERSION)" echo - "$PREFIX/bin/makensis" -HDRINFO + "$BINDIR/makensis" -HDRINFO