diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index eda8544..0000000 --- a/.editorconfig +++ /dev/null @@ -1,60 +0,0 @@ -# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/general/.editorconfig -# See: https://editorconfig.org/ -# The formatting style defined in this file is the official standardized style to be used in all Arduino Tooling -# projects and should not be modified. -# Note: indent style for each file type is defined even when it matches the universal config in order to make it clear -# that this type has an official style. - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.{adoc,asc,asciidoc}] -indent_size = 2 -indent_style = space - -[*.{bash,sh}] -indent_size = 2 -indent_style = space - -[*.{c,cc,cp,cpp,cxx,h,hh,hpp,hxx,ii,inl,ino,ixx,pde,tpl,tpp,txx}] -indent_size = 2 -indent_style = space - -[*.{go,mod}] -indent_style = tab - -[*.java] -indent_size = 2 -indent_style = space - -[*.{js,jsx,json,jsonc,json5,ts,tsx}] -indent_size = 2 -indent_style = space - -[*.{md,mdx,mkdn,mdown,markdown}] -indent_size = unset -indent_style = space - -[*.proto] -indent_size = 2 -indent_style = space - -[*.py] -indent_size = 4 -indent_style = space - -[*.svg] -indent_size = 2 -indent_style = space - -[*.{yaml,yml}] -indent_size = 2 -indent_style = space - -[{.gitconfig,.gitmodules}] -indent_style = tab diff --git a/.github/workflows/check-shell-task.yml b/.github/workflows/check-shell-task.yml deleted file mode 100644 index f6cd3bd..0000000 --- a/.github/workflows/check-shell-task.yml +++ /dev/null @@ -1,177 +0,0 @@ -# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-shell-task.md -name: Check Shell Scripts - -# See: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows -on: - create: - push: - paths: - - ".github/workflows/check-shell-task.ya?ml" - - "Taskfile.ya?ml" - - "**/.editorconfig" - - "**.bash" - - "**.sh" - pull_request: - paths: - - ".github/workflows/check-shell-task.ya?ml" - - "Taskfile.ya?ml" - - "**/.editorconfig" - - "**.bash" - - "**.sh" - schedule: - # Run every Tuesday at 8 AM UTC to catch breakage caused by tool changes. - - cron: "0 8 * * TUE" - workflow_dispatch: - repository_dispatch: - -jobs: - run-determination: - runs-on: ubuntu-latest - outputs: - result: ${{ steps.determination.outputs.result }} - steps: - - name: Determine if the rest of the workflow should run - id: determination - run: | - RELEASE_BRANCH_REGEX="refs/heads/[0-9]+.[0-9]+.x" - # The `create` event trigger doesn't support `branches` filters, so it's necessary to use Bash instead. - if [[ - "${{ github.event_name }}" != "create" || - "${{ github.ref }}" =~ $RELEASE_BRANCH_REGEX - ]]; then - # Run the other jobs. - RESULT="true" - else - # There is no need to run the other jobs. - RESULT="false" - fi - - echo "::set-output name=result::$RESULT" - - lint: - name: ${{ matrix.configuration.name }} - needs: run-determination - if: needs.run-determination.outputs.result == 'true' - runs-on: ubuntu-latest - - env: - # See: https://github.com/koalaman/shellcheck/releases/latest - SHELLCHECK_RELEASE_ASSET_SUFFIX: .linux.x86_64.tar.xz - - strategy: - fail-fast: false - - matrix: - configuration: - - name: Generate problem matcher output - # ShellCheck's "gcc" output format is required for annotated diffs, but inferior for humans reading the log. - format: gcc - # The other matrix job is used to set the result, so this job is configured to always pass. - continue-on-error: true - - name: ShellCheck - # ShellCheck's "tty" output format is most suitable for humans reading the log. - format: tty - continue-on-error: false - - steps: - - name: Set environment variables - run: | - # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable - echo "INSTALL_PATH=${{ runner.temp }}/shellcheck" >> "$GITHUB_ENV" - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install Task - uses: arduino/setup-task@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - version: 3.x - - - name: Download latest ShellCheck release binary package - id: download - uses: MrOctopus/download-asset-action@1.0 - with: - repository: koalaman/shellcheck - excludes: prerelease, draft - asset: ${{ env.SHELLCHECK_RELEASE_ASSET_SUFFIX }} - target: ${{ env.INSTALL_PATH }} - - - name: Install ShellCheck - run: | - cd "${{ env.INSTALL_PATH }}" - tar --extract --file="${{ steps.download.outputs.name }}" - EXTRACTION_FOLDER="$(basename "${{ steps.download.outputs.name }}" "${{ env.SHELLCHECK_RELEASE_ASSET_SUFFIX }}")" - # Add installation to PATH: - # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path - echo "${{ env.INSTALL_PATH }}/$EXTRACTION_FOLDER" >> "$GITHUB_PATH" - - - name: Run ShellCheck - uses: liskin/gh-problem-matcher-wrap@v1 - continue-on-error: ${{ matrix.configuration.continue-on-error }} - with: - linters: gcc - run: task --silent shell:check SHELLCHECK_FORMAT=${{ matrix.configuration.format }} - - formatting: - needs: run-determination - if: needs.run-determination.outputs.result == 'true' - runs-on: ubuntu-latest - - steps: - - name: Set environment variables - run: | - # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#setting-an-environment-variable - echo "SHFMT_INSTALL_PATH=${{ runner.temp }}/shfmt" >> "$GITHUB_ENV" - - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install Task - uses: arduino/setup-task@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - version: 3.x - - - name: Download shfmt - id: download - uses: MrOctopus/download-asset-action@1.0 - with: - repository: mvdan/sh - excludes: prerelease, draft - asset: _linux_amd64 - target: ${{ env.SHFMT_INSTALL_PATH }} - - - name: Install shfmt - run: | - # Executable permissions of release assets are lost - chmod +x "${{ env.SHFMT_INSTALL_PATH }}/${{ steps.download.outputs.name }}" - # Standardize binary name - mv "${{ env.SHFMT_INSTALL_PATH }}/${{ steps.download.outputs.name }}" "${{ env.SHFMT_INSTALL_PATH }}/shfmt" - # Add installation to PATH: - # See: https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path - echo "${{ env.SHFMT_INSTALL_PATH }}" >> "$GITHUB_PATH" - - - name: Format shell scripts - run: task --silent shell:format - - - name: Check formatting - run: git diff --color --exit-code - - executable: - needs: run-determination - if: needs.run-determination.outputs.result == 'true' - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v3 - - - name: Install Task - uses: arduino/setup-task@v1 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - version: 3.x - - - name: Check for non-executable scripts - run: task --silent shell:check-mode diff --git a/.github/workflows/check-taskfiles.yml b/.github/workflows/check-taskfiles.yml index e1b2903..79412b8 100644 --- a/.github/workflows/check-taskfiles.yml +++ b/.github/workflows/check-taskfiles.yml @@ -13,12 +13,14 @@ on: - "package.json" - "package-lock.json" - "**/Taskfile.ya?ml" + - "**/DistTasks.ya?ml" pull_request: paths: - ".github/workflows/check-taskfiles.ya?ml" - "package.json" - "package-lock.json" - "**/Taskfile.ya?ml" + - "**/DistTasks.ya?ml" schedule: # Run every Tuesday at 8 AM UTC to catch breakage resulting from changes to the JSON schema. - cron: "0 8 * * TUE" @@ -37,6 +39,7 @@ jobs: file: # TODO: add paths to any additional Taskfiles here - ./**/Taskfile.yml + - ./**/DistTasks.yml steps: - name: Checkout repository diff --git a/.github/workflows/release-go-crosscompile-task.yml b/.github/workflows/release-go-crosscompile-task.yml new file mode 100644 index 0000000..5af7509 --- /dev/null +++ b/.github/workflows/release-go-crosscompile-task.yml @@ -0,0 +1,224 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/release-go-crosscompile-task.md +name: Release + +env: + # As defined by the Taskfile's PROJECT_NAME variable + PROJECT_NAME: arduinoOTA + # As defined by the Taskfile's DIST_DIR variable + DIST_DIR: dist + # The project's folder on Arduino's download server for uploading builds + AWS_PLUGIN_TARGET: /arduinoOTA/ + ARTIFACT_NAME: dist + # See: https://github.com/actions/setup-go/tree/main#supported-version-syntax + GO_VERSION: "1.17" + +on: + push: + tags: + - "[0-9]+.[0-9]+.[0-9]+*" + +jobs: + create-release-artifacts: + runs-on: ubuntu-latest + + strategy: + matrix: + os: + - Windows_32bit + - Windows_64bit + - Linux_32bit + - Linux_64bit + - Linux_ARMv6 + - Linux_ARMv7 + - Linux_ARM64 + - macOS_64bit + - macOS_ARM64 + + steps: + - name: Checkout repository + uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Create changelog + # Avoid creating the same changelog for each os + if: matrix.os == 'Windows_32bit' + uses: arduino/create-changelog@v1 + with: + tag-regex: '^[0-9]+\.[0-9]+\.[0-9]+.*$' + filter-regex: '^\[(skip|changelog)[ ,-](skip|changelog)\].*' + case-insensitive-regex: true + changelog-file-path: "${{ env.DIST_DIR }}/CHANGELOG.md" + + - name: Install Go + uses: actions/setup-go@v3 + with: + go-version: ${{ env.GO_VERSION }} + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Build + run: task dist:${{ matrix.os }} + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + with: + if-no-files-found: error + name: ${{ env.ARTIFACT_NAME }} + path: ${{ env.DIST_DIR }} + + notarize-macos: + 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 + + strategy: + matrix: + artifact: + - name: darwin_amd64 + path: "macOS_64bit.tar.gz" + - name: darwin_arm64 + path: "macOS_ARM64.tar.gz" + + 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: Import Code-Signing Certificates + env: + KEYCHAIN: "sign.keychain" + INSTALLER_CERT_MAC_PATH: "/tmp/ArduinoCerts2020.p12" + KEYCHAIN_PASSWORD: keychainpassword # Arbitrary password for a keychain that exists only for the duration of the job, so not secret + run: | + echo "${{ secrets.INSTALLER_CERT_MAC_P12 }}" | base64 --decode > "${{ env.INSTALLER_CERT_MAC_PATH }}" + security create-keychain -p "${{ env.KEYCHAIN_PASSWORD }}" "${{ env.KEYCHAIN }}" + security default-keychain -s "${{ env.KEYCHAIN }}" + security unlock-keychain -p "${{ env.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 "${{ env.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 > "${{ env.GON_CONFIG_PATH }}" <> $GITHUB_ENV + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + if-no-files-found: error + name: ${{ env.ARTIFACT_NAME }} + path: ${{ env.DIST_DIR }}/${{ env.PACKAGE_FILENAME }} + + create-release: + runs-on: ubuntu-latest + needs: notarize-macos + + steps: + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: ${{ env.ARTIFACT_NAME }} + path: ${{ env.DIST_DIR }} + + - name: Create checksum file + working-directory: ${{ env.DIST_DIR}} + run: | + TAG="${GITHUB_REF/refs\/tags\//}" + sha256sum ${{ env.PROJECT_NAME }}_${TAG}* > ${TAG}-checksums.txt + + - name: Identify Prerelease + # This is a workaround while waiting for create-release action + # to implement auto pre-release based on tag + id: prerelease + run: | + wget -q -P /tmp https://github.com/fsaintjacques/semver-tool/archive/3.2.0.zip + unzip -p /tmp/3.2.0.zip semver-tool-3.2.0/src/semver >/tmp/semver && chmod +x /tmp/semver + if [[ "$(/tmp/semver get prerel "${GITHUB_REF/refs\/tags\//}")" ]]; then echo "IS_PRE=true" >> $GITHUB_OUTPUT; fi + + - name: Create Github Release and upload artifacts + uses: ncipollo/release-action@v1 + with: + token: ${{ secrets.GITHUB_TOKEN }} + bodyFile: ${{ env.DIST_DIR }}/CHANGELOG.md + draft: false + prerelease: ${{ steps.prerelease.outputs.IS_PRE }} + # NOTE: "Artifact is a directory" warnings are expected and don't indicate a problem + # (all the files we need are in the DIST_DIR root) + artifacts: ${{ env.DIST_DIR }}/* + + - name: Upload release files on Arduino downloads servers + uses: docker://plugins/s3 + env: + PLUGIN_SOURCE: "${{ env.DIST_DIR }}/*" + PLUGIN_TARGET: ${{ env.AWS_PLUGIN_TARGET }} + PLUGIN_STRIP_PREFIX: "${{ env.DIST_DIR }}/" + PLUGIN_BUCKET: ${{ secrets.DOWNLOADS_BUCKET }} + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} diff --git a/DistTasks.yml b/DistTasks.yml new file mode 100644 index 0000000..9274993 --- /dev/null +++ b/DistTasks.yml @@ -0,0 +1,158 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-crosscompile-task/DistTasks.yml +version: "3" + +# This taskfile is ideally meant to be project agnostic and could be dropped in +# on other Go projects with minimal or no changes. +# +# To use it simply add the following lines to your main taskfile: +# includes: +# dist: ./DistTasks.yml +# +# The following variables must be declared in the including taskfile for the +# build process to work correctly: +# * DIST_DIR: the folder that will contain the final binaries and packages +# * PROJECT_NAME: the name of the project, used in package name +# * VERSION: the version of the project, used in package name and checksum file +# * LD_FLAGS: flags used at build time +# +# The project MUST contain a LICENSE.txt file in the root folder or packaging will fail. + +tasks: + Windows_32bit: + desc: Builds Windows 32 bit binaries + env: + GOOS: "windows" + GOARCH: "386" + GO386: "softfloat" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}} + cd {{.DIST_DIR}} + zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_386" + PACKAGE_PLATFORM: "Windows_32bit" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip" + + Windows_64bit: + desc: Builds Windows 64 bit binaries + env: + GOOS: "windows" + GOARCH: "amd64" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe {{.LDFLAGS}} + cd {{.DIST_DIR}} + zip {{.PACKAGE_NAME}} {{.PLATFORM_DIR}}/{{.PROJECT_NAME}}.exe ../LICENSE.txt -j + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_windows_amd64" + PACKAGE_PLATFORM: "Windows_64bit" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.zip" + + Linux_32bit: + desc: Builds Linux 32 bit binaries + env: + GOOS: "linux" + GOARCH: "386" + GO386: "softfloat" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd32" + PACKAGE_PLATFORM: "Linux_32bit" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + Linux_64bit: + desc: Builds Linux 64 bit binaries + env: + GOOS: "linux" + GOARCH: "amd64" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_amd64" + PACKAGE_PLATFORM: "Linux_64bit" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + Linux_ARMv7: + desc: Builds Linux ARMv7 binaries + env: + GOOS: "linux" + GOARCH: "arm" + GOARM: 7 + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_7" + PACKAGE_PLATFORM: "Linux_ARMv7" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + Linux_ARMv6: + desc: Builds Linux ARMv6 binaries + env: + GOOS: "linux" + GOARCH: "arm" + GOARM: 6 + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_6" + PACKAGE_PLATFORM: "Linux_ARMv6" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + Linux_ARM64: + desc: Builds Linux ARM64 binaries + env: + GOOS: "linux" + GOARCH: "arm64" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_linux_arm_64" + PACKAGE_PLATFORM: "Linux_ARM64" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + macOS_64bit: + desc: Builds Mac OS X 64 bit binaries + env: + GOOS: "darwin" + GOARCH: "amd64" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_osx_darwin_amd64" + PACKAGE_PLATFORM: "macOS_64bit" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" + + macOS_ARM64: + desc: Builds Mac OS X ARM64 binaries + env: + GOOS: "darwin" + GOARCH: "arm64" + cmds: + - | + go build -o {{.DIST_DIR}}/{{.PLATFORM_DIR}}/{{.PROJECT_NAME}} {{.LDFLAGS}} + cd {{.DIST_DIR}} + tar cz -C {{.PLATFORM_DIR}} {{.PROJECT_NAME}} -C ../.. LICENSE.txt -f {{.PACKAGE_NAME}} + vars: + PLATFORM_DIR: "{{.PROJECT_NAME}}_osx_darwin_arm64" + PACKAGE_PLATFORM: "macOS_ARM64" + PACKAGE_NAME: "{{.PROJECT_NAME}}_{{.VERSION}}_{{.PACKAGE_PLATFORM}}.tar.gz" diff --git a/README.md b/README.md index c9f8a6a..06bd938 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,12 @@ [![Check Prettier Formatting status](https://github.com/arduino/arduinoOTA/actions/workflows/check-prettier-formatting-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-prettier-formatting-task.yml) [![Spell Check status](https://github.com/arduino/arduinoOTA/actions/workflows/spell-check-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/spell-check-task.yml) [![Check Markdown status](https://github.com/arduino/arduinoOTA/actions/workflows/check-markdown-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-markdown-task.yml) -[![Check Shell Scripts status](https://github.com/arduino/arduinoOTA/actions/workflows/check-shell-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-shell-task.yml) [![Check Taskfiles status](https://github.com/arduino/arduinoOTA/actions/workflows/check-taskfiles.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-taskfiles.yml) [![Check Workflows status](https://github.com/arduino/arduinoOTA/actions/workflows/check-workflows-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-workflows-task.yml) [![Check YAML status](https://github.com/arduino/arduinoOTA/actions/workflows/check-yaml-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-yaml-task.yml) [![Check License status](https://github.com/arduino/arduinoOTA/actions/workflows/check-license.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/check-license.yml) [![Sync Labels status](https://github.com/arduino/arduinoOTA/actions/workflows/sync-labels-npm.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/sync-labels-npm.yml) +[![Release status](https://github.com/arduino/arduinoOTA/actions/workflows/release-go-crosscompile-task.yml/badge.svg)](https://github.com/arduino/arduinoOTA/actions/workflows/release-go-crosscompile-task.yml) **arduinoOTA** is a tool for uploading programs to [Arduino](https://arduino.cc/) boards over a network. diff --git a/Taskfile.yml b/Taskfile.yml index ce06a8d..46c41f2 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -1,7 +1,31 @@ # See: https://taskfile.dev/#/usage version: "3" +includes: + dist: ./DistTasks.yml + vars: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/release-go-task/Taskfile.yml + PROJECT_NAME: "arduinoOTA" + DIST_DIR: "dist" + # build vars + COMMIT: + sh: echo "$(git log --no-show-signature -n 1 --format=%h)" + TIMESTAMP: + sh: echo "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" + TIMESTAMP_SHORT: + sh: echo "{{now | date "20060102"}}" + TAG: + sh: echo "$(git tag --points-at=HEAD 2> /dev/null | head -n1)" + VERSION: "{{if .NIGHTLY}}nightly-{{.TIMESTAMP_SHORT}}{{else if .TAG}}{{.TAG}}{{else}}{{.PACKAGE_NAME_PREFIX}}git-snapshot{{end}}" + CONFIGURATION_PACKAGE: "github.com/arduino/arduinoOTA/version" + LDFLAGS: >- + -ldflags + ' + -X {{.CONFIGURATION_PACKAGE}}.versionString={{.VERSION}} + -X {{.CONFIGURATION_PACKAGE}}.commit={{.COMMIT}} + -X {{.CONFIGURATION_PACKAGE}}.date={{.TIMESTAMP}} + ' # Path of the project's primary Go module: DEFAULT_GO_MODULE_PATH: ./ DEFAULT_GO_PACKAGES: @@ -283,81 +307,6 @@ tasks: cmds: - poetry install --no-root - # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-shell-task/Taskfile.yml - shell:check: - desc: Check for problems with shell scripts - cmds: - - | - if ! which shellcheck &>/dev/null; then - echo "shellcheck not installed or not in PATH. Please install: https://github.com/koalaman/shellcheck#installing" - exit 1 - fi - - | - # There is something odd about shellcheck that causes the task to always exit on the first fail, despite any - # measures that would prevent this with any other command. So it's necessary to call shellcheck only once with - # the list of script paths as an argument. This could lead to exceeding the maximum command length on Windows if - # the repository contained a large number of scripts, but it's unlikely to happen in reality. - shellcheck \ - --format={{default "tty" .SHELLCHECK_FORMAT}} \ - $( - # The odd method for escaping . in the regex is required for windows compatibility because mvdan.cc/sh gives - # \ characters special treatment on Windows in an attempt to support them as path separators. - find . \ - -type d -name '.git' -prune -or \ - -type d -name '.licenses' -prune -or \ - -type d -name '__pycache__' -prune -or \ - -type d -name 'node_modules' -prune -or \ - \( \ - -regextype posix-extended \ - -regex '.*[.](bash|sh)' -and \ - -type f \ - \) \ - -print - ) - - # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-shell-task/Taskfile.yml - shell:check-mode: - desc: Check for non-executable shell scripts - cmds: - - | - EXIT_STATUS=0 - while read -r nonExecutableScriptPath; do - # The while loop always runs once, even if no file was found - if [[ "$nonExecutableScriptPath" == "" ]]; then - continue - fi - - echo "::error file=${nonExecutableScriptPath}::non-executable script file: $nonExecutableScriptPath"; - EXIT_STATUS=1 - done <<<"$( - # The odd approach to escaping `.` in the regex is required for windows compatibility because mvdan.cc/sh - # gives `\` characters special treatment on Windows in an attempt to support them as path separators. - find . \ - -type d -name '.git' -prune -or \ - -type d -name '.licenses' -prune -or \ - -type d -name '__pycache__' -prune -or \ - -type d -name 'node_modules' -prune -or \ - \( \ - -regextype posix-extended \ - -regex '.*[.](bash|sh)' -and \ - -type f -and \ - -not -executable \ - -print \ - \) - )" - exit $EXIT_STATUS - - # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-shell-task/Taskfile.yml - shell:format: - desc: Format shell script files - cmds: - - | - if ! which shfmt &>/dev/null; then - echo "shfmt not installed or not in PATH. Please install: https://github.com/mvdan/sh#shfmt" - exit 1 - fi - - shfmt -w . - # Make a temporary file named according to the passed TEMPLATE variable and print the path passed to stdout # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/windows-task/Taskfile.yml utility:mktemp-file: diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index 1d8518e..0000000 --- a/deploy.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash -xe -GIT_REV="$(git log --pretty=format:'%h' -n 1)" -BUILD_DATE="$(date +%Y-%m-%d:%H:%M:%S)" -COMPILEINFO="$(echo "+${GIT_REV}+${BUILD_DATE}" | tr -d '"')" - -VERSION="$(grep "const AppVersion" main.go | cut -f4 -d " " | tr -d '"')" - -#Remember to set GOROOT accordingly with your installation - -export GOPATH=$PWD -export CGO_ENABLED=false - -rm -rf distrib/ - -declare -a target_folders=("linux_amd64" "linux_386" "linux_arm" "darwin_amd64" "windows_386" "linux_arm64") - -mkdir distrib - -for folder in "${target_folders[@]}"; do - - IFS=_ read -r -a fields <<<"$folder" - mkdir -p "distrib/${folder}/bin/" - GOOS="${fields[0]}" GOARCH="${fields[1]}" go build -o "distrib/${folder}/bin/arduinoOTA" -ldflags "-X main.compileInfo=$COMPILEINFO" main.go -done - -#Fix windows binary extension -mv distrib/windows_386/bin/arduinoOTA distrib/windows_386/bin/arduinoOTA.exe - -cd distrib - -for folder in "${target_folders[@]}"; do - mv "$folder" arduinoOTA - if [[ $folder == "windows_386" ]]; then - zip -r "arduinoOTA-${VERSION}-${folder}.zip" arduinoOTA/ - else - tar cjf "arduinoOTA-${VERSION}-${folder}.tar.bz2" arduinoOTA/ - fi - rm -rf arduinoOTA -done - -echo ======= -ls -la arduinoOTA* -echo ======= -sha256sum arduinoOTA* -echo ======= -shasum arduinoOTA* diff --git a/globals/globals.go b/globals/globals.go new file mode 100644 index 0000000..a5d2bce --- /dev/null +++ b/globals/globals.go @@ -0,0 +1,13 @@ +package globals + +import ( + "os" + "path/filepath" + + "github.com/arduino/arduinoOTA/version" +) + +var ( + // VersionInfo contains all info injected during build + VersionInfo = version.NewInfo(filepath.Base(os.Args[0])) +) diff --git a/main.go b/main.go index c716195..6455435 100644 --- a/main.go +++ b/main.go @@ -15,10 +15,9 @@ import ( "strconv" "strings" "time" -) -// AppVersion is the application version. -const AppVersion = "1.3.0" + "github.com/arduino/arduinoOTA/globals" +) var compileInfo string @@ -45,7 +44,7 @@ func main() { flag.Parse() if *version { - fmt.Println(AppVersion + compileInfo) + fmt.Println(globals.VersionInfo.String() + compileInfo) os.Exit(0) } diff --git a/version/version.go b/version/version.go new file mode 100644 index 0000000..3f7261e --- /dev/null +++ b/version/version.go @@ -0,0 +1,39 @@ +package version + +import "fmt" + +var ( + defaultVersionString = "0.0.0-git" + versionString = "" + commit = "" + date = "" +) + +// Info is a struct that contains information about the application +type Info struct { + Application string `json:"Application"` + VersionString string `json:"VersionString"` + Commit string `json:"Commit"` + Date string `json:"Date"` +} + +// NewInfo returns a pointer to an updated Info struct +func NewInfo(application string) *Info { + return &Info{ + Application: application, + VersionString: versionString, + Commit: commit, + Date: date, + } +} + +func (i *Info) String() string { + return fmt.Sprintf("%[1]s Version: %[2]s Commit: %[3]s Date: %[4]s", i.Application, i.VersionString, i.Commit, i.Date) +} + +//nolint:gochecknoinits +func init() { + if versionString == "" { + versionString = defaultVersionString + } +}