diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..3acfbb48c --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,363 @@ +name: release + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + +jobs: + # The build job is responsible for: configuring the environment, testing and compiling process + build: + strategy: + matrix: + operating-system: [ubuntu-latest, windows-latest, macos-latest] + + runs-on: ${{ matrix.operating-system }} + + steps: + - name: Disable EOL conversions + run: git config --global core.autocrlf false + + - name: Checkout + uses: actions/checkout@v2 + + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version: "1.15" + + # dependencies used for compiling the GUI + - name: Install Dependencies (Linux) + run: sudo apt update && sudo apt install -y --no-install-recommends build-essential libgtk-3-dev libwebkit2gtk-4.0-dev libappindicator3-dev + if: matrix.operating-system == 'ubuntu-latest' + + - name: Install Go deps + # Since 10/23/2019 pwsh is the default shell + # on Windows, but pwsh fails to install protoc-gen-go so + # we force bash as default shell for all OSes in this task + run: | + go get github.com/golangci/govet + go get golang.org/x/lint/golint + shell: bash + + - name: Install Taskfile + uses: arduino/actions/setup-taskfile@master + with: + version: '3.x' + repo-token: ${{ secrets.GITHUB_TOKEN }} + + - name: Check the code is good + run: task check + + - name: Run unit tests + run: task test-unit + + - name: Build the Agent + run: task build + if: matrix.operating-system != 'windows-latest' + + # build the agent without GUI support (no tray icon) + - name: Build the Agent-cli + run: task build-cli + if: matrix.operating-system == 'ubuntu-latest' + + # the manifest is required by windows GUI apps, otherwise the binary will crash with: "Unable to create main window: TTM_ADDTOOL failed" (for reference https://github.com/lxn/walk/issues/28) + # rsrc will produce *.syso files that should get automatically recognized by go build command and linked into an executable. + - name: Embed manifest in win binary + run: | + go get github.com/akavel/rsrc + rsrc -arch 386 -manifest manifest.xml + if: matrix.operating-system == 'windows-latest' + + # building the agent for win requires a different task because of an extra flag + - name: Build the Agent for win32 + env: + GOARCH: 386 # 32bit architecture (for support) + GO386: 387 # support old instruction sets without MMX (used in the Pentium 4) (will be deprecated in GO > 1.15 https://golang.org/doc/go1.15) + run: task build-win32 + if: matrix.operating-system == 'windows-latest' + + # config.ini is required by the executable when it's run + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: arduino-create-agent-${{ matrix.operating-system }} + path: | + arduino-create-agent* + config.ini + if-no-files-found: error + + # The code-sign-mac-executable job will download the macos artifact from the previous job, sign e notarize the binary and re-upload it. + code-sign-mac-executable: + needs: build + runs-on: macos-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + repository: 'bcmi-labs/arduino-create-agent-installer' # the repo which contains gon.config.hcl + token: ${{ secrets.ARDUINO_CREATE_AGENT_CI_PAT }} + + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: arduino-create-agent-macos-latest + path: arduino-create-agent-macos-latest + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_PATH }} + security create-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + security default-keychain -s ${{ env.KEYCHAIN }} + security unlock-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + security import ${{ env.INSTALLER_CERT_MAC_PATH }} -k ${{ env.KEYCHAIN }} -f pkcs12 -A -T /usr/bin/codesign -P ${{ secrets.INSTALLER_CERT_MAC_PASSWORD }} + security set-key-partition-list -S apple-tool:,apple: -s -k ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Code sign and notarize app + env: + AC_USERNAME: ${{ secrets.AC_USERNAME }} + AC_PASSWORD: ${{ secrets.AC_PASSWORD }} + run: | + gon -log-level=debug -log-json gon.config.hcl + # gon will notarize executable in "arduino-create-agent-macos-latest/arduino-create-agent + # The CI will ignore the zip output, using the signed binary only. + timeout-minutes: 30 + + # This step will overwrite the non signed mac artifact (arduino-create-agent-macos-latest) + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: arduino-create-agent-macos-latest + path: arduino-create-agent-macos-latest + if-no-files-found: error + + # This job is responsible for generating the installers (using installbuilder) + package: + needs: code-sign-mac-executable + runs-on: ubuntu-latest + + env: + # vars used by installbuilder + INSTALLBUILDER_PATH: "/opt/installbuilder-20.9.0/bin/builder" + INSTALLER_VARS: "project.outputDirectory=$PWD project.version=${GITHUB_REF##*/} workspace=$PWD realname=Arduino_Create_Bridge" + # vars passed to installbuilder to install https certs automatically + CERT_INSTALL: "ask_certificates_install=CI" # win(edge),mac(safari) + NO_CERT_INSTALL: "ask_certificates_install=CS" # linux + CHOICE_CERT_INSTALL: "ask_certificates_install=CC" # win,mac:(ff,chrome) + CREATE_OSX_BUNDLED_MG: 0 # tell installbuilder to not create the DMG, gon will take care of that later + # installbuilder will read this vars automatically (defined in installer.xml): + INSTALLER_CERT_WINDOWS_PASSWORD: ${{ secrets.INSTALLER_CERT_WINDOWS_PASSWORD }} + INSTALLER_CERT_WINDOWS_PFX: "/tmp/ArduinoCerts2020.pfx" + INSTALLER_CERT_MAC_PASSWORD: ${{ secrets.INSTALLER_CERT_MAC_PASSWORD }} + INSTALLER_CERT_MAC_P12: "/tmp/ArduinoCerts2020.p12" + + strategy: + fail-fast: false # if one os is failing continue nonetheless + matrix: # used to generate installers for different OS and not for runs-on + operating-system: [ubuntu-latest, windows-latest, macos-latest] + + include: + - operating-system: ubuntu-latest + install-builder-name: linux-x64 + executable-path: artifacts/linux-amd64/ + - operating-system: windows-latest + browser: edge + install-builder-name: windows + executable-path: artifacts/windows/ + extension: .exe + installer-extension: .exe + - operating-system: macos-latest + browser: safari + install-builder-name: osx + executable-path: 'skel/ArduinoCreateAgent.app/Contents/MacOS/' + installer-extension: .app + + container: + image: floydpink/ubuntu-install-builder:20.9.0 + + steps: + + - name: Checkout + uses: actions/checkout@v2 + with: + repository: 'bcmi-labs/arduino-create-agent-installer' # the repo which contains install.xml + token: ${{ secrets.ARDUINO_CREATE_AGENT_CI_PAT }} + + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: arduino-create-agent-${{ matrix.operating-system }} + path: ${{ matrix.executable-path }} # path expected by installbuilder + + # zip artifacts do not mantain executable permission + - name: Make executable + run: chmod -v +x ${{ matrix.executable-path }}arduino-create-agent* + if: matrix.operating-system == 'ubuntu-latest' || matrix.operating-system == 'macos-latest' + + - name: Rename executable to Arduino_Create_Bridge + run: mv -v ${{ matrix.executable-path }}arduino-create-agent${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Bridge${{ matrix.extension }} + + - name: Rename executable to Arduino_Create_Bridge_cli + run: mv -v ${{ matrix.executable-path }}arduino-create-agent_cli${{ matrix.extension }} ${{ matrix.executable-path }}Arduino_Create_Bridge_cli${{ matrix.extension }} + if: matrix.operating-system == 'ubuntu-latest' + + - name: Save InstallBuilder license to file + run: echo "${{ secrets.INSTALLER_LICENSE }}" > /tmp/license.xml + + - name: Save Win signing certificate to file + run: echo "${{ secrets.INSTALLER_CERT_WINDOWS_PFX }}" | base64 --decode > ${{ env.INSTALLER_CERT_WINDOWS_PFX}} + if: matrix.operating-system == 'windows-latest' + + - name: Save macos signing certificate to file + run: echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_P12 }} + if: matrix.operating-system == 'macos-latest' + + # win(edge),mac(safari) -> CERT_INSTALL and win,mac:(ff,chrome) -> CHOICE_CERT_INSTALL + # installbuilder reads the env vars with certs paths and use it to sign the installer. + - name: Launch Bitrock installbuilder-20 with CERT_INSTALL && CHOICE_CERT_INSTALL + run: | + ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.CERT_INSTALL }} + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CI${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-${{matrix.browser}}${{matrix.installer-extension}} + ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.CHOICE_CERT_INSTALL }} + cp -vr ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-chrome${{matrix.installer-extension}} + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CC${{matrix.installer-extension}} ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-firefox${{matrix.installer-extension}} + rm -r ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-C* + if: matrix.operating-system == 'windows-latest' || matrix.operating-system == 'macos-latest' + + # linux + - name: Launch Bitrock installbuilder-20 with NO_CERT_INSTALL + run: | + ${{ env.INSTALLBUILDER_PATH }} build installer.xml ${{ matrix.install-builder-name }} --verbose --license /tmp/license.xml --setvars ${{ env.INSTALLER_VARS }} ${{ env.NO_CERT_INSTALL }} + cp -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CS.run ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-chrome.run + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CS.run ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-firefox.run + cp -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CS.tar.gz ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-chrome.tar.gz + mv -v ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-CS.tar.gz ArduinoCreateAgent-${GITHUB_REF##*/}-${{ matrix.install-builder-name }}-installer-firefox.tar.gz + if: matrix.operating-system == 'ubuntu-latest' + + - name: Upload artifacts + uses: actions/upload-artifact@v2 + with: + name: ArduinoCreateAgent-${{ matrix.install-builder-name }} + path: ArduinoCreateAgent* + if-no-files-found: error + + # This job will sign and notarize mac installers + code-sign-mac-installers: + needs: package + runs-on: macos-latest + + strategy: + matrix: + browser: [safari, firefox, chrome] + + steps: + + - name: Download artifact + uses: actions/download-artifact@v2 + with: + name: ArduinoCreateAgent-osx + path: ArduinoCreateAgent-osx + + # zip artifacts do not mantain executable permission + - name: Make executable + run: chmod -v +x ArduinoCreateAgent-osx/ArduinoCreateAgent-${GITHUB_REF##*/}-osx-installer-${{ matrix.browser }}.app/Contents/MacOS/* + + - name: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > ${{ env.INSTALLER_CERT_MAC_PATH }} + security create-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + security default-keychain -s ${{ env.KEYCHAIN }} + security unlock-keychain -p ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + security import ${{ env.INSTALLER_CERT_MAC_PATH }} -k ${{ env.KEYCHAIN }} -f pkcs12 -A -T /usr/bin/codesign -P ${{ secrets.INSTALLER_CERT_MAC_PASSWORD }} + security set-key-partition-list -S apple-tool:,apple: -s -k ${{ secrets.KEYCHAIN_PASSWORD }} ${{ env.KEYCHAIN }} + + - name: Install gon for code signing and app notarization + run: | + wget -q https://github.com/mitchellh/gon/releases/download/v0.2.3/gon_macos.zip + unzip gon_macos.zip -d /usr/local/bin + + - name: Write gon config to file + # gon does not allow env variables in config file (https://github.com/mitchellh/gon/issues/20) + run: | + cat > gon.config_installer.hcl < - # matrix.operating-system == 'ubuntu-latest' && - # github.event_name == 'push' - # uses: codecov/codecov-action@v1 - # with: - # file: ./coverage_unit.txt - # flags: unit + # build the agent without GUI support (no tray icon) + - name: Build the Agent-cli + run: task build-cli + if: matrix.operating-system == 'ubuntu-latest' - # - name: Send legacy tests coverage to Codecov - # if: > - # matrix.operating-system == 'ubuntu-latest' && - # github.event_name == 'push' - # uses: codecov/codecov-action@v1 - # with: - # file: ./coverage_legacy.txt - # flags: unit + # the manifest is required by windows GUI apps, otherwise the binary will crash with: "Unable to create main window: TTM_ADDTOOL failed" (for reference https://github.com/lxn/walk/issues/28) + # rsrc will produce *.syso files that should get automatically recognized by go build command and linked into an executable. + - name: Embed manifest in win binary + run: | + go get github.com/akavel/rsrc + rsrc -arch 386 -manifest manifest.xml + if: matrix.operating-system == 'windows-latest' - # - name: Send integration tests coverage to Codecov - # if: > - # matrix.operating-system == 'ubuntu-latest' && - # github.event_name == 'push' - # uses: codecov/codecov-action@v1 - # with: - # file: ./coverage_integ.txt - # flags: integ + # building the agent for win requires a different task because of an extra flag + - name: Build the Agent for win32 + env: + GOARCH: 386 # 32bit architecture (for support) + GO386: 387 # support old instruction sets without MMX (used in the Pentium 4) (will be deprecated in GO > 1.15 https://golang.org/doc/go1.15) + run: task build-win32 + if: matrix.operating-system == 'windows-latest' diff --git a/.gitignore b/.gitignore index 692d029fe..cd1c063ca 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,6 @@ artifacts* # IDEs config .idea + +# macOS +.DS_Store diff --git a/Taskfile.yml b/Taskfile.yml index d822a68df..fed3fdee7 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -7,13 +7,15 @@ tasks: cmds: - go build -v -i {{.LDFLAGS}} - build-win: - desc: Build the project for win + build-cli: + desc: Build the project without tray support + cmds: + - go build -v -i -tags cli -o {{.APP_NAME}}_cli {{.LDFLAGS}} + + build-win32: + desc: Build the project for win 32 bit cmds: - - go get github.com/akavel/rsrc - - rsrc -arch=386 -manifest=manifest.xml - go build -v -i {{.WIN_LDFLAGS}} - - rm rsrc.syso test: desc: Run the full testsuite, `legacy` will be skipped @@ -47,6 +49,7 @@ vars: DEFAULT_TARGETS: sh: echo `go list ./... | grep -v 'arduino-create-agent/gen/' | tr '\n' ' '` # build vars + APP_NAME: arduino-create-agent WIN_FLAGS: -H=windowsgui COMMIT: sh: echo ${TRAVIS_COMMIT:-`git log -n 1 --format=%h`}