diff --git a/.github/workflows/check-certificates.yml b/.github/workflows/check-certificates.yml
index 589dd2412ed..9ca01502255 100644
--- a/.github/workflows/check-certificates.yml
+++ b/.github/workflows/check-certificates.yml
@@ -36,6 +36,9 @@ jobs:
- identifier: macOS signing certificate # Text used to identify certificate in notifications.
certificate-secret: INSTALLER_CERT_MAC_P12 # Name of the secret that contains the certificate.
password-secret: INSTALLER_CERT_MAC_PASSWORD # Name of the secret that contains the certificate password.
+ - identifier: Windows signing certificate
+ certificate-secret: INSTALLER_CERT_WINDOWS_PASSWORD
+ password-secret: INSTALLER_CERT_WINDOWS_PFX
steps:
- name: Set certificate path environment variable
diff --git a/.github/workflows/publish-go-nightly-task.yml b/.github/workflows/publish-go-nightly-task.yml
index 6ddc4e7e7fc..821673c8ce0 100644
--- a/.github/workflows/publish-go-nightly-task.yml
+++ b/.github/workflows/publish-go-nightly-task.yml
@@ -20,6 +20,8 @@ on:
jobs:
create-nightly-artifacts:
+ outputs:
+ version: ${{ steps.get-version.outputs.version }}
runs-on: ubuntu-latest
strategy:
@@ -50,6 +52,12 @@ jobs:
NIGHTLY: true
run: task dist:${{ matrix.os }}
+ - name: Output Version
+ id: get-version
+ env:
+ NIGHTLY: true
+ run: echo "::set-output name=version::$(task general:get-version)"
+
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
@@ -61,9 +69,6 @@ jobs:
name: Notarize ${{ matrix.artifact.name }}
runs-on: macos-latest
needs: create-nightly-artifacts
- outputs:
- checksum-darwin_amd64: ${{ steps.re-package.outputs.checksum-darwin_amd64 }}
- checksum-darwin_arm64: ${{ steps.re-package.outputs.checksum-darwin_arm64 }}
env:
GON_CONFIG_PATH: gon.config.hcl
@@ -141,15 +146,14 @@ jobs:
gon "${{ env.GON_CONFIG_PATH }}"
- name: Re-package binary
- id: re-package
working-directory: ${{ env.DIST_DIR }}
# Repackage the signed binary replaced in place by Gon (ignoring the output zip file)
run: |
# GitHub's upload/download-artifact@v2 actions don't preserve file permissions,
# so we need to add execution permission back until the action is made to do this.
chmod +x "${{ env.PROJECT_NAME }}_osx_${{ matrix.artifact.name }}/${{ env.PROJECT_NAME }}"
- # Use of an array here is required for globbing
- PACKAGE_FILENAME=(${{ env.PROJECT_NAME }}_nightly-*${{ matrix.artifact.path }})
+ VERSION=${{ needs.create-nightly-artifacts.outputs.version }}
+ PACKAGE_FILENAME=(${{ env.PROJECT_NAME }}_${VERSION}_${{ matrix.artifact.path }})
tar -czvf "$PACKAGE_FILENAME" \
-C "${{ env.PROJECT_NAME }}_osx_${{ matrix.artifact.name }}/" "${{ env.PROJECT_NAME }}" \
-C ../../ LICENSE.txt
@@ -162,9 +166,68 @@ jobs:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.DIST_DIR }}/${{ env.PACKAGE_FILENAME }}
+ create-windows-installer:
+ runs-on: windows-latest
+ needs: create-nightly-artifacts
+
+ defaults:
+ run:
+ shell: bash
+
+ env:
+ INSTALLER_CERT_WINDOWS_PFX: "/tmp/cert.pfx"
+ # We are hardcoding the path for signtool because is not present on the windows PATH env var by default.
+ # Keep in mind that this path could change when upgrading to a new runner version
+ # https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md#installed-windows-sdks
+ SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x86/signtool.exe"
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Download artifacts
+ uses: actions/download-artifact@v3
+ with:
+ name: ${{ env.ARTIFACT_NAME }}
+ path: ${{ env.DIST_DIR }}
+
+ - name: Prepare PATH
+ uses: microsoft/setup-msbuild@v1
+
+ - name: Build MSI
+ id: buildmsi
+ run: |
+ VERSION=${{ needs.create-nightly-artifacts.outputs.version }}
+ WIX_VERSION="0.0.0" # use 0.0.0 as version for the installer since wix is picky about other alternatives, this only affects nightly builds (error CNDL0242)
+ PACKAGE_FILENAME="${{ env.PROJECT_NAME }}_${VERSION}_Windows_64bit"
+ SOURCE_DIR="${GITHUB_WORKSPACE}/${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_windows_amd64/"
+ MSBuild.exe ./installer/cli.wixproj -p:SourceDir="$SOURCE_DIR" -p:OutputPath="${GITHUB_WORKSPACE}/${{ env.DIST_DIR }}" -p:OutputName="$PACKAGE_FILENAME" -p:ProductVersion="$WIX_VERSION"
+
+ - name: Save Win signing certificate to file
+ run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_PFX }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_PFX}}
+
+ - name: Sign MSI
+ env:
+ MSI_FILE: ${{ steps.buildmsi.outputs.msi }} # this comes from .installer/cli.wixproj
+ CERT_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
+ run: |
+ "${{ env.SIGNTOOL_PATH }}" sign -d "Arduino CLI" -f ${{ env.INSTALLER_CERT_WINDOWS_PFX}} -p ${{ env.CERT_PASSWORD }} -fd sha256 -tr http://timestamp.digicert.com -td SHA256 -v "${{ env.MSI_FILE }}"
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v3
+ env:
+ MSI_FILE: ${{ steps.buildmsi.outputs.msi }}
+ with:
+ if-no-files-found: error
+ name: ${{ env.ARTIFACT_NAME }}
+ path: ${{ env.MSI_FILE }}
+
publish-nightly:
runs-on: ubuntu-latest
- needs: notarize-macos
+ needs:
+ - create-nightly-artifacts
+ - notarize-macos
+ - create-windows-installer
steps:
- name: Download artifact
@@ -176,8 +239,8 @@ jobs:
- name: Create checksum file
working-directory: ${{ env.DIST_DIR}}
run: |
- TAG="nightly-$(date -u +"%Y%m%d")"
- sha256sum ${{ env.PROJECT_NAME }}_${TAG}* > ${TAG}-checksums.txt
+ VERSION=${{ needs.create-nightly-artifacts.outputs.version }}
+ sha256sum ${{ env.PROJECT_NAME }}_${VERSION}* > ${VERSION}-checksums.txt
- name: Upload release files on Arduino downloads servers
uses: docker://plugins/s3
diff --git a/.github/workflows/release-go-task.yml b/.github/workflows/release-go-task.yml
index 8c27721899e..5d026f422bb 100644
--- a/.github/workflows/release-go-task.yml
+++ b/.github/workflows/release-go-task.yml
@@ -17,6 +17,8 @@ on:
jobs:
create-release-artifacts:
+ outputs:
+ version: ${{ steps.get-version.outputs.version }}
runs-on: ubuntu-latest
strategy:
@@ -57,6 +59,10 @@ jobs:
- name: Build
run: task dist:${{ matrix.os }}
+ - name: Output Version
+ id: get-version
+ run: echo "::set-output name=version::$(task general:get-version)"
+
- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
@@ -68,9 +74,6 @@ jobs:
name: Notarize ${{ matrix.artifact.name }}
runs-on: macos-latest
needs: create-release-artifacts
- outputs:
- checksum-darwin_amd64: ${{ steps.re-package.outputs.checksum-darwin_amd64 }}
- checksum-darwin_arm64: ${{ steps.re-package.outputs.checksum-darwin_arm64 }}
env:
GON_CONFIG_PATH: gon.config.hcl
@@ -148,14 +151,13 @@ jobs:
gon "${{ env.GON_CONFIG_PATH }}"
- name: Re-package binary
- id: re-package
working-directory: ${{ env.DIST_DIR }}
# Repackage the signed binary replaced in place by Gon (ignoring the output zip file)
run: |
# GitHub's upload/download-artifact@v2 actions don't preserve file permissions,
# so we need to add execution permission back until the action is made to do this.
chmod +x "${{ env.PROJECT_NAME }}_osx_${{ matrix.artifact.name }}/${{ env.PROJECT_NAME }}"
- TAG="${GITHUB_REF/refs\/tags\//}"
+ TAG=${{ needs.create-release-artifacts.outputs.version }}
PACKAGE_FILENAME="${{ env.PROJECT_NAME }}_${TAG}_${{ matrix.artifact.path }}"
tar -czvf "$PACKAGE_FILENAME" \
-C "${{ env.PROJECT_NAME }}_osx_${{ matrix.artifact.name }}/" "${{ env.PROJECT_NAME }}" \
@@ -169,9 +171,68 @@ jobs:
name: ${{ env.ARTIFACT_NAME }}
path: ${{ env.DIST_DIR }}/${{ env.PACKAGE_FILENAME }}
+ create-windows-installer:
+ runs-on: windows-latest
+ needs: create-release-artifacts
+
+ defaults:
+ run:
+ shell: bash
+
+ env:
+ INSTALLER_CERT_WINDOWS_PFX: "/tmp/cert.pfx"
+ # We are hardcoding the path for signtool because is not present on the windows PATH env var by default.
+ # Keep in mind that this path could change when upgrading to a new runner version
+ # https://github.com/actions/runner-images/blob/main/images/win/Windows2022-Readme.md#installed-windows-sdks
+ SIGNTOOL_PATH: "C:/Program Files (x86)/Windows Kits/10/bin/10.0.22621.0/x86/signtool.exe"
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v3
+
+ - name: Download artifacts
+ uses: actions/download-artifact@v3
+ with:
+ name: ${{ env.ARTIFACT_NAME }}
+ path: ${{ env.DIST_DIR }}
+
+ - name: Prepare PATH
+ uses: microsoft/setup-msbuild@v1
+
+ - name: Build MSI
+ id: buildmsi
+ run: |
+ TAG=${{ needs.create-release-artifacts.outputs.version }}
+ WIX_TAG="${TAG%%-*}" # removes "-rc*" since wix is not happy with it, this only affects RCs builds (error CNDL0108)
+ PACKAGE_FILENAME="${{ env.PROJECT_NAME }}_${TAG}_Windows_64bit"
+ SOURCE_DIR="${GITHUB_WORKSPACE}/${{ env.DIST_DIR }}/${{ env.PROJECT_NAME }}_windows_amd64/"
+ MSBuild.exe ./installer/cli.wixproj -p:SourceDir="$SOURCE_DIR" -p:OutputPath="${GITHUB_WORKSPACE}/${{ env.DIST_DIR }}" -p:OutputName="$PACKAGE_FILENAME" -p:ProductVersion="$WIX_TAG"
+
+ - name: Save Win signing certificate to file
+ run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_PFX }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_PFX}}
+
+ - name: Sign MSI
+ env:
+ MSI_FILE: ${{ steps.buildmsi.outputs.msi }} # this comes from .installer/cli.wixproj
+ CERT_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }}
+ run: |
+ "${{ env.SIGNTOOL_PATH }}" sign -d "Arduino CLI" -f ${{ env.INSTALLER_CERT_WINDOWS_PFX}} -p ${{ env.CERT_PASSWORD }} -fd sha256 -tr http://timestamp.digicert.com -td SHA256 -v "${{ env.MSI_FILE }}"
+
+ - name: Upload artifacts
+ uses: actions/upload-artifact@v3
+ env:
+ MSI_FILE: ${{ steps.buildmsi.outputs.msi }}
+ with:
+ if-no-files-found: error
+ name: ${{ env.ARTIFACT_NAME }}
+ path: ${{ env.MSI_FILE }}
+
create-release:
runs-on: ubuntu-latest
- needs: notarize-macos
+ needs:
+ - create-release-artifacts
+ - notarize-macos
+ - create-windows-installer
steps:
- name: Download artifact
@@ -183,7 +244,7 @@ jobs:
- name: Create checksum file
working-directory: ${{ env.DIST_DIR}}
run: |
- TAG="${GITHUB_REF/refs\/tags\//}"
+ TAG=${{ needs.create-release-artifacts.outputs.version }}
sha256sum ${{ env.PROJECT_NAME }}_${TAG}* > ${TAG}-checksums.txt
- name: Identify Prerelease
@@ -193,7 +254,7 @@ jobs:
run: |
wget -q -P /tmp https://github.com/fsaintjacques/semver-tool/archive/3.0.0.zip
unzip -p /tmp/3.0.0.zip semver-tool-3.0.0/src/semver >/tmp/semver && chmod +x /tmp/semver
- if [[ "$(/tmp/semver get prerel "${GITHUB_REF/refs\/tags\//}")" ]]; then echo "::set-output name=IS_PRE::true"; fi
+ if [[ "$(/tmp/semver get prerel ${{ needs.create-release-artifacts.outputs.version }} )" ]]; then echo "::set-output name=IS_PRE::true"; fi
- name: Create Github Release and upload artifacts
uses: ncipollo/release-action@v1
diff --git a/.prettierignore b/.prettierignore
index 26aad378ce1..3b34afa1ed6 100644
--- a/.prettierignore
+++ b/.prettierignore
@@ -8,3 +8,4 @@
/arduino/security/testdata/
/.licenses/
/site/
+/installer/
\ No newline at end of file
diff --git a/Taskfile.yml b/Taskfile.yml
index 9d24febc3b1..23a2b6561aa 100755
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -327,6 +327,11 @@ tasks:
cmds:
- poetry run mkdocs serve
+ general:get-version:
+ desc: Returns the version used in the project
+ cmds:
+ - echo {{.VERSION}}
+
vars:
PROJECT_NAME: "arduino-cli"
DIST_DIR: "dist"
diff --git a/docs/installation.md b/docs/installation.md
index 9677997ac43..6a444fe4bfc 100644
--- a/docs/installation.md
+++ b/docs/installation.md
@@ -58,13 +58,14 @@ in your [`PATH`](https://en.wikipedia.org/wiki/PATH%5F%28variable%29) or add the
### Latest release
-| Platform | | |
-| --------- | -------------------- | -------------------- |
-| Linux | [32 bit][linux32] | [64 bit][linux64] |
-| Linux ARM | [32 bit][linuxarm32] | [64 bit][linuxarm64] |
-| Windows | [32 bit][windows32] | [64 bit][windows64] |
-| macOS | | [64 bit][macos64] |
-| macOS ARM | | [64 bit][macosarm64] |
+| Platform | | |
+| ----------- | -------------------- | ---------------------- |
+| Linux | [32 bit][linux32] | [64 bit][linux64] |
+| Linux ARM | [32 bit][linuxarm32] | [64 bit][linuxarm64] |
+| Windows exe | [32 bit][windows32] | [64 bit][windows64] |
+| Windows msi | | [64 bit][windowsmsi64] |
+| macOS | | [64 bit][macos64] |
+| macOS ARM | | [64 bit][macosarm64] |
[linux64]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_64bit.tar.gz
[linux32]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_32bit.tar.gz
@@ -72,6 +73,7 @@ in your [`PATH`](https://en.wikipedia.org/wiki/PATH%5F%28variable%29) or add the
[linuxarm32]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Linux_ARMv7.tar.gz
[windows64]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.zip
[windows32]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_32bit.zip
+[windowsmsi64]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_Windows_64bit.msi
[macos64]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_macOS_64bit.tar.gz
[macosarm64]: https://downloads.arduino.cc/arduino-cli/arduino-cli_latest_macOS_ARM64.tar.gz
@@ -88,13 +90,14 @@ These are available from the "Assets" sections on the [releases page](https://gi
These builds are generated every day at 01:00 GMT from the `master` branch and should be considered unstable. In order
to get the latest nightly build available for the supported platform, use the following links:
-| Platform | | |
-| --------- | ---------------------------- | ---------------------------- |
-| Linux | [32 bit][linux32-nightly] | [64 bit][linux64-nightly] |
-| Linux ARM | [32 bit][linuxarm32-nightly] | [64 bit][linuxarm64-nightly] |
-| Windows | [32 bit][windows32-nightly] | [64 bit][windows64-nightly] |
-| macOS | | [64 bit][macos64-nightly] |
-| macOS ARM | | [64 bit][macosarm64-nightly] |
+| Platform | | |
+| ----------- | ---------------------------- | ------------------------------ |
+| Linux | [32 bit][linux32-nightly] | [64 bit][linux64-nightly] |
+| Linux ARM | [32 bit][linuxarm32-nightly] | [64 bit][linuxarm64-nightly] |
+| Windows exe | [32 bit][windows32-nightly] | [64 bit][windows64-nightly] |
+| Windows msi | | [64 bit][windowsmsi64-nightly] |
+| macOS | | [64 bit][macos64-nightly] |
+| macOS ARM | | [64 bit][macosarm64-nightly] |
[linux64-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_64bit.tar.gz
[linux32-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_32bit.tar.gz
@@ -102,6 +105,7 @@ to get the latest nightly build available for the supported platform, use the fo
[linuxarm32-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Linux_ARMv7.tar.gz
[windows64-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Windows_64bit.zip
[windows32-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Windows_32bit.zip
+[windowsmsi64-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_Windows_64bit.msi
[macos64-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_macOS_64bit.tar.gz
[macosarm64-nightly]: https://downloads.arduino.cc/arduino-cli/nightly/arduino-cli_nightly-latest_macOS_ARM64.tar.gz
diff --git a/installer/cli.wixproj b/installer/cli.wixproj
new file mode 100644
index 00000000000..e574aa9f168
--- /dev/null
+++ b/installer/cli.wixproj
@@ -0,0 +1,39 @@
+
+
+
+ Release
+ x64
+
+ 0.1.0
+
+ $(MSBuildProjectName)
+ package
+
+ $(DefineConstants);
+ ProductVersion=$(ProductVersion);
+
+ false
+ $(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/cli.wxs b/installer/cli.wxs
new file mode 100644
index 00000000000..0a3731edda2
--- /dev/null
+++ b/installer/cli.wxs
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/installer/ui.wxs b/installer/ui.wxs
new file mode 100644
index 00000000000..5de8cf2c3d7
--- /dev/null
+++ b/installer/ui.wxs
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1
+ "1"]]>
+
+ 1
+
+ NOT Installed
+ Installed AND PATCH
+
+ 1
+ 1
+ NOT WIXUI_DONTVALIDATEPATH
+ "1"]]>
+ WIXUI_DONTVALIDATEPATH OR WIXUI_INSTALLDIR_VALID="1"
+ 1
+ 1
+
+ NOT Installed
+ Installed AND NOT PATCH
+ Installed AND PATCH
+
+ 1
+
+ 1
+ 1
+ 1
+
+
+
+
+
+
+
\ No newline at end of file