From 2e1a5cb286b5a68394a6d299986b64351c1f19cf Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 13:14:37 -0700 Subject: [PATCH 01/18] Use appropriate file extension for license file This file is not written in Markdown, so the previous `.md` file extension was incorrect. The options for an appropriate standardized file name are: - `LICENSE.txt` - `LICENSE` I chose the former because the file is in text format and the `.txt` file extension clearly communicates this to humans and machines both, making the information in the file more accessible than would be the case with the latter file name. This is the standard license file name in Arduino tooling projects for this reason. --- LICENSE.md => LICENSE.txt | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename LICENSE.md => LICENSE.txt (100%) diff --git a/LICENSE.md b/LICENSE.txt similarity index 100% rename from LICENSE.md rename to LICENSE.txt From 5eaab89d31df8471d6dbc758d71f0b5f41333f8d Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:52:30 -0700 Subject: [PATCH 02/18] Add CI workflow to check the license file Whenever one of the recognized license file names are modified in the repository, the workflow runs to check whether the license can be recognized and whether it is of the expected type. GitHub has a useful automated license detection system that determines the license type used by a repository, and surfaces that information in the repository home page, the search web interface, and the GitHub API. This license detection system requires that the license be defined by a dedicated file with one of several standardized filenames and paths. GitHub's license detection system uses the popular licensee tool, so this file also serves to define the license type for any other usages of licensee, as well as to human readers of the file. For this reason, and to ensure it remains a valid legal instrument, it's important that there be no non-standard modifications to the license file or collisions with other supported license files. This workflow ensures that any changes which would change the license type or which license file is used by the detection are caught automatically. --- .github/workflows/check-license.yml | 67 +++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/check-license.yml diff --git a/.github/workflows/check-license.yml b/.github/workflows/check-license.yml new file mode 100644 index 0000000..d93c4d7 --- /dev/null +++ b/.github/workflows/check-license.yml @@ -0,0 +1,67 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-license.md +name: Check License + +env: + EXPECTED_LICENSE_FILENAME: LICENSE.txt + # SPDX identifier: https://spdx.org/licenses/ + EXPECTED_LICENSE_TYPE: GPL-3.0 + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/check-license.ya?ml" + # See: https://github.com/licensee/licensee/blob/master/docs/what-we-look-at.md#detecting-the-license-file + - "[cC][oO][pP][yY][iI][nN][gG]*" + - "[cC][oO][pP][yY][rR][iI][gG][hH][tH]*" + - "[lL][iI][cC][eE][nN][cCsS][eE]*" + - "[oO][fF][lL]*" + - "[pP][aA][tT][eE][nN][tT][sS]*" + pull_request: + paths: + - ".github/workflows/check-license.ya?ml" + - "[cC][oO][pP][yY][iI][nN][gG]*" + - "[cC][oO][pP][yY][rR][iI][gG][hH][tH]*" + - "[lL][iI][cC][eE][nN][cCsS][eE]*" + - "[oO][fF][lL]*" + - "[pP][aA][tT][eE][nN][tT][sS]*" + workflow_dispatch: + repository_dispatch: + +jobs: + check-license: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: ruby # Install latest version + + - name: Install licensee + run: gem install licensee + + - name: Check license file + run: | + EXIT_STATUS=0 + # See: https://github.com/licensee/licensee + LICENSEE_OUTPUT="$(licensee detect --json --confidence=100)" + + DETECTED_LICENSE_FILE="$(echo "$LICENSEE_OUTPUT" | jq .matched_files[0].filename | tr --delete '\r')" + echo "Detected license file: $DETECTED_LICENSE_FILE" + if [ "$DETECTED_LICENSE_FILE" != "\"${EXPECTED_LICENSE_FILENAME}\"" ]; then + echo "::error file=${DETECTED_LICENSE_FILE}::detected license file $DETECTED_LICENSE_FILE doesn't match expected: $EXPECTED_LICENSE_FILENAME" + EXIT_STATUS=1 + fi + + DETECTED_LICENSE_TYPE="$(echo "$LICENSEE_OUTPUT" | jq .matched_files[0].matched_license | tr --delete '\r')" + echo "Detected license type: $DETECTED_LICENSE_TYPE" + if [ "$DETECTED_LICENSE_TYPE" != "\"${EXPECTED_LICENSE_TYPE}\"" ]; then + echo "::error file=${DETECTED_LICENSE_FILE}::detected license type $DETECTED_LICENSE_TYPE doesn't match expected \"${EXPECTED_LICENSE_TYPE}\"" + EXIT_STATUS=1 + fi + + exit $EXIT_STATUS From 0ad34ddbba01aa68b6d930d692fef045f6a9c79b Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:53:00 -0700 Subject: [PATCH 03/18] Add CI workflow to check general file formatting On every push, pull request, and periodically, check whether the repository's files are formatted according to .editorconfig. --- .ecrc | 6 ++ .editorconfig | 60 +++++++++++++++++++ .../check-general-formatting-task.yml | 53 ++++++++++++++++ Taskfile.yml | 14 +++++ 4 files changed, 133 insertions(+) create mode 100644 .ecrc create mode 100644 .editorconfig create mode 100644 .github/workflows/check-general-formatting-task.yml create mode 100644 Taskfile.yml diff --git a/.ecrc b/.ecrc new file mode 100644 index 0000000..888b8f0 --- /dev/null +++ b/.ecrc @@ -0,0 +1,6 @@ +{ + "Exclude": [ + "^LICENSE\\.txt$", + "^poetry\\.lock$" + ] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..eda8544 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,60 @@ +# 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-general-formatting-task.yml b/.github/workflows/check-general-formatting-task.yml new file mode 100644 index 0000000..c1460dd --- /dev/null +++ b/.github/workflows/check-general-formatting-task.yml @@ -0,0 +1,53 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-general-formatting-task.md +name: Check General Formatting + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + pull_request: + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage caused by changes to tools. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + + steps: + - name: Set environment variables + run: | + # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable + echo "EC_INSTALL_PATH=${{ runner.temp }}/editorconfig-checker" >> "$GITHUB_ENV" + + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Download latest editorconfig-checker release binary package + id: download + uses: MrOctopus/download-asset-action@1.0 + with: + repository: editorconfig-checker/editorconfig-checker + excludes: prerelease, draft + asset: linux-amd64.tar.gz + target: ${{ env.EC_INSTALL_PATH }} + + - name: Install editorconfig-checker + run: | + cd "${{ env.EC_INSTALL_PATH }}" + tar --extract --file="${{ steps.download.outputs.name }}" + # Give the binary a standard name + mv "${{ env.EC_INSTALL_PATH }}/bin/ec-linux-amd64" "${{ env.EC_INSTALL_PATH }}/bin/ec" + # Add installation to PATH: + # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#adding-a-system-path + echo "${{ env.EC_INSTALL_PATH }}/bin" >> "$GITHUB_PATH" + + - name: Check formatting + run: task --silent general:check-formatting diff --git a/Taskfile.yml b/Taskfile.yml new file mode 100644 index 0000000..db0c447 --- /dev/null +++ b/Taskfile.yml @@ -0,0 +1,14 @@ +# See: https://taskfile.dev/#/usage +version: "3" + +tasks: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-general-formatting-task/Taskfile.yml + general:check-formatting: + desc: Check basic formatting style of all files + cmds: + - | + if ! which ec &>/dev/null; then + echo "ec not found or not in PATH. Please install: https://github.com/editorconfig-checker/editorconfig-checker#installation" + exit 1 + fi + - ec From 0f0e98639c60c167a6e749b2f593b9ed896a8817 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:57:23 -0700 Subject: [PATCH 04/18] Add CI workflow to check for Prettier formatting compliance On every push and pull request that affects relevant files, check whether the formatting of supported files is compliant with the Prettier style. --- .../check-prettier-formatting-task.yml | 219 ++++++++++++++++++ Taskfile.yml | 6 + 2 files changed, 225 insertions(+) create mode 100644 .github/workflows/check-prettier-formatting-task.yml diff --git a/.github/workflows/check-prettier-formatting-task.yml b/.github/workflows/check-prettier-formatting-task.yml new file mode 100644 index 0000000..caccbcf --- /dev/null +++ b/.github/workflows/check-prettier-formatting-task.yml @@ -0,0 +1,219 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-prettier-formatting-task.md +name: Check Prettier Formatting + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/check-prettier-formatting-task.ya?ml" + - "Taskfile.ya?ml" + - "**/.prettierignore" + - "**/.prettierrc*" + # CSS + - "**.css" + - "**.wxss" + # PostCSS + - "**.pcss" + - "**.postcss" + # Less + - "**.less" + # SCSS + - "**.scss" + # GraphQL + - "**.graphqls?" + - "**.gql" + # handlebars + - "**.handlebars" + - "**.hbs" + # HTML + - "**.mjml" + - "**.html?" + - "**.html.hl" + - "**.st" + - "**.xht" + - "**.xhtml" + # Vue + - "**.vue" + # JavaScript + - "**.flow" + - "**._?jsb?" + - "**.bones" + - "**.cjs" + - "**.es6?" + - "**.frag" + - "**.gs" + - "**.jake" + - "**.jscad" + - "**.jsfl" + - "**.js[ms]" + - "**.[mn]js" + - "**.pac" + - "**.wxs" + - "**.[xs]s?js" + - "**.xsjslib" + # JSX + - "**.jsx" + # TypeScript + - "**.ts" + # TSX + - "**.tsx" + # JSON + - "**/.eslintrc" + - "**.json" + - "**.avsc" + - "**.geojson" + - "**.gltf" + - "**.har" + - "**.ice" + - "**.JSON-tmLanguage" + - "**.mcmeta" + - "**.tfstate" + - "**.topojson" + - "**.webapp" + - "**.webmanifest" + - "**.yyp?" + # JSONC + - "**/.babelrc" + - "**/.jscsrc" + - "**/.js[hl]intrc" + - "**.jsonc" + - "**.sublime-*" + # JSON5 + - "**.json5" + # Markdown + - "**.mdx?" + - "**.markdown" + - "**.mk?down" + - "**.mdwn" + - "**.mkdn?" + - "**.ronn" + - "**.workbook" + # YAML + - "**/.clang-format" + - "**/.clang-tidy" + - "**/.gemrc" + - "**/glide.lock" + - "**.ya?ml*" + - "**.mir" + - "**.reek" + - "**.rviz" + - "**.sublime-syntax" + - "**.syntax" + pull_request: + paths: + - ".github/workflows/check-prettier-formatting-task.ya?ml" + - "Taskfile.ya?ml" + - "**/.prettierignore" + - "**/.prettierrc*" + # CSS + - "**.css" + - "**.wxss" + # PostCSS + - "**.pcss" + - "**.postcss" + # Less + - "**.less" + # SCSS + - "**.scss" + # GraphQL + - "**.graphqls?" + - "**.gql" + # handlebars + - "**.handlebars" + - "**.hbs" + # HTML + - "**.mjml" + - "**.html?" + - "**.html.hl" + - "**.st" + - "**.xht" + - "**.xhtml" + # Vue + - "**.vue" + # JavaScript + - "**.flow" + - "**._?jsb?" + - "**.bones" + - "**.cjs" + - "**.es6?" + - "**.frag" + - "**.gs" + - "**.jake" + - "**.jscad" + - "**.jsfl" + - "**.js[ms]" + - "**.[mn]js" + - "**.pac" + - "**.wxs" + - "**.[xs]s?js" + - "**.xsjslib" + # JSX + - "**.jsx" + # TypeScript + - "**.ts" + # TSX + - "**.tsx" + # JSON + - "**/.eslintrc" + - "**.json" + - "**.avsc" + - "**.geojson" + - "**.gltf" + - "**.har" + - "**.ice" + - "**.JSON-tmLanguage" + - "**.mcmeta" + - "**.tfstate" + - "**.topojson" + - "**.webapp" + - "**.webmanifest" + - "**.yyp?" + # JSONC + - "**/.babelrc" + - "**/.jscsrc" + - "**/.js[hl]intrc" + - "**.jsonc" + - "**.sublime-*" + # JSON5 + - "**.json5" + # Markdown + - "**.mdx?" + - "**.markdown" + - "**.mk?down" + - "**.mdwn" + - "**.mkdn?" + - "**.ronn" + - "**.workbook" + # YAML + - "**/.clang-format" + - "**/.clang-tidy" + - "**/.gemrc" + - "**/glide.lock" + - "**.ya?ml*" + - "**.mir" + - "**.reek" + - "**.rviz" + - "**.sublime-syntax" + - "**.syntax" + workflow_dispatch: + repository_dispatch: + +jobs: + check: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Format with Prettier + run: task general:format-prettier + + - name: Check formatting + run: git diff --color --exit-code diff --git a/Taskfile.yml b/Taskfile.yml index db0c447..a98dc63 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -12,3 +12,9 @@ tasks: exit 1 fi - ec + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-prettier-formatting-task/Taskfile.yml + general:format-prettier: + desc: Format all supported files with Prettier + cmds: + - npx prettier --write . From e2f30b060438695fc33ad0c201c9185e9bad3f10 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:58:20 -0700 Subject: [PATCH 05/18] Add CI workflow to check for problems with shell scripts On every push or pull request that modifies one of the shell scripts in the repository, and periodically, the workflow: - Runs ShellCheck to detect common problems. - Runs shfmt to check formatting. - Checks for forgotten executable script file permissions. --- .github/workflows/check-shell-task.yml | 147 +++++++++++++++++++++++++ Taskfile.yml | 68 ++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 .github/workflows/check-shell-task.yml diff --git a/.github/workflows/check-shell-task.yml b/.github/workflows/check-shell-task.yml new file mode 100644 index 0000000..8b8bb0c --- /dev/null +++ b/.github/workflows/check-shell-task.yml @@ -0,0 +1,147 @@ +# 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/en/actions/reference/events-that-trigger-workflows +on: + 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: + lint: + name: ${{ matrix.configuration.name }} + 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/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable + echo "INSTALL_PATH=${{ runner.temp }}/shellcheck" >> "$GITHUB_ENV" + + - name: Checkout repository + uses: actions/checkout@v2 + + - 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/en/actions/reference/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: + runs-on: ubuntu-latest + + steps: + - name: Set environment variables + run: | + # See: https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-environment-variable + echo "SHFMT_INSTALL_PATH=${{ runner.temp }}/shfmt" >> "$GITHUB_ENV" + + - name: Checkout repository + uses: actions/checkout@v2 + + - 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/en/actions/reference/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: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - 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/Taskfile.yml b/Taskfile.yml index a98dc63..745f91b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -18,3 +18,71 @@ tasks: desc: Format all supported files with Prettier cmds: - npx prettier --write . + + # 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 . \ + -path ".git" -prune -or \ + \( \ + -regextype posix-extended \ + -regex '.*[.](bash|sh)' -and \ + -type f \ + \) + ) + + # 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 . \ + -path ".git" -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 . From 5d650ce5df1e7266564ad7319f38b9f398a34d3b Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:59:01 -0700 Subject: [PATCH 06/18] Add CI workflow to validate Taskfiles On every push or pull request that affects the repository's Taskfiles, and periodically, validate them against the JSON schema. --- .github/workflows/check-taskfiles.yml | 60 +++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/workflows/check-taskfiles.yml diff --git a/.github/workflows/check-taskfiles.yml b/.github/workflows/check-taskfiles.yml new file mode 100644 index 0000000..45e306a --- /dev/null +++ b/.github/workflows/check-taskfiles.yml @@ -0,0 +1,60 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-taskfiles.md +name: Check Taskfiles + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/check-taskfiles.ya?ml" + - "**/Taskfile.ya?ml" + pull_request: + paths: + - ".github/workflows/check-taskfiles.ya?ml" + - "**/Taskfile.ya?ml" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage resulting from changes to the JSON schema. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + validate: + name: Validate ${{ matrix.file }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + file: + # TODO: add paths to any additional Taskfiles here + - ./**/Taskfile.yml + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Download JSON schema for Taskfiles + id: download-schema + uses: carlosperate/download-file-action@v1.0.3 + with: + # See: https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/taskfile.json + file-url: https://json.schemastore.org/taskfile.json + location: ${{ runner.temp }}/taskfile-schema + + - name: Install JSON schema validator + run: | + sudo npm install \ + --global \ + ajv-cli \ + ajv-formats + + - name: Validate ${{ matrix.file }} + run: | + # See: https://github.com/ajv-validator/ajv-cli#readme + ajv validate \ + --all-errors \ + --strict=false \ + -c ajv-formats \ + -s "${{ steps.download-schema.outputs.file-path }}" \ + -d "${{ matrix.file }}" From 63f7175120f242c255803fc9b31374ad1c468e80 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 18:59:46 -0700 Subject: [PATCH 07/18] Add CI workflow to validate GitHub Actions workflows On every push or pull request that affects the repository's GitHub Actions workflows, and periodically, validate them against the JSON schema. --- .github/workflows/check-workflows-task.yml | 35 ++++++++++++++++++++++ Taskfile.yml | 26 ++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 .github/workflows/check-workflows-task.yml diff --git a/.github/workflows/check-workflows-task.yml b/.github/workflows/check-workflows-task.yml new file mode 100644 index 0000000..5d433c4 --- /dev/null +++ b/.github/workflows/check-workflows-task.yml @@ -0,0 +1,35 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/master/workflow-templates/check-workflows-task.md +name: Check Workflows + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/*.ya?ml" + - "Taskfile.ya?ml" + pull_request: + paths: + - ".github/workflows/*.ya?ml" + - "Taskfile.ya?ml" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage resulting from changes to the JSON schema. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + validate: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Validate workflows + run: task --silent ci:validate diff --git a/Taskfile.yml b/Taskfile.yml index 745f91b..67b82c1 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -2,6 +2,32 @@ version: "3" tasks: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-workflows-task/Taskfile.yml + ci:validate: + desc: Validate GitHub Actions workflows against their JSON schema + vars: + # Source: https://github.com/SchemaStore/schemastore/blob/master/src/schemas/json/github-workflow.json + WORKFLOW_SCHEMA_URL: https://json.schemastore.org/github-workflow + WORKFLOW_SCHEMA_PATH: + sh: mktemp -t workflow-schema-XXXXXXXXXX.json + WORKFLOWS_DATA_PATH: "./.github/workflows/*.{yml,yaml}" + cmds: + - | + wget \ + --quiet \ + --output-document="{{.WORKFLOW_SCHEMA_PATH}}" \ + {{.WORKFLOW_SCHEMA_URL}} + - | + npx \ + --package=ajv-cli \ + --package=ajv-formats \ + ajv validate \ + --all-errors \ + --strict=false \ + -c ajv-formats \ + -s "{{.WORKFLOW_SCHEMA_PATH}}" \ + -d "{{.WORKFLOWS_DATA_PATH}}" + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-general-formatting-task/Taskfile.yml general:check-formatting: desc: Check basic formatting style of all files From 3d1d8ba568e82e88c4002fdf4cf76c348f44b368 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:03:00 -0700 Subject: [PATCH 08/18] Add CI workflow to lint YAML files On every push and pull request that affects relevant files, run yamllint to check the YAML files of the repository for issues. The .yamllint.yml file is used to configure yamllint: https://yamllint.readthedocs.io/en/stable/configuration.html --- .github/workflows/check-yaml-task.yml | 85 +++++++++++++++++++++++++++ .yamllint.yml | 74 +++++++++++++++++++++++ Taskfile.yml | 14 +++++ poetry.lock | 72 +++++++++++++++++++++++ pyproject.toml | 15 +++++ 5 files changed, 260 insertions(+) create mode 100644 .github/workflows/check-yaml-task.yml create mode 100644 .yamllint.yml create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/.github/workflows/check-yaml-task.yml b/.github/workflows/check-yaml-task.yml new file mode 100644 index 0000000..54b5f87 --- /dev/null +++ b/.github/workflows/check-yaml-task.yml @@ -0,0 +1,85 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-yaml-task.md +name: Check YAML + +env: + # See: https://github.com/actions/setup-python/tree/v2#available-versions-of-python + PYTHON_VERSION: "3.9" + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".yamllint*" + - "poetry.lock" + - "pyproject.toml" + # Source: https://github.com/ikatyang/linguist-languages/blob/master/data/YAML.json (used by Prettier) + - "**/.clang-format" + - "**/.clang-tidy" + - "**/.gemrc" + - "**/glide.lock" + - "**.ya?ml*" + - "**.mir" + - "**.reek" + - "**.rviz" + - "**.sublime-syntax" + - "**.syntax" + pull_request: + paths: + - ".yamllint*" + - "poetry.lock" + - "pyproject.toml" + # Source: https://github.com/ikatyang/linguist-languages/blob/master/data/YAML.json (used by Prettier) + - "**/.clang-format" + - "**/.clang-tidy" + - "**/.gemrc" + - "**/glide.lock" + - "**.ya?ml*" + - "**.mir" + - "**.reek" + - "**.rviz" + - "**.sublime-syntax" + - "**.syntax" + workflow_dispatch: + repository_dispatch: + +jobs: + check: + name: ${{ matrix.configuration.name }} + runs-on: ubuntu-latest + + strategy: + fail-fast: false + + matrix: + configuration: + - name: Generate problem matcher output + # yamllint's "github" output type produces annotated diffs, but is not useful to humans reading the log. + format: github + # The other matrix job is used to set the result, so this job is configured to always pass. + continue-on-error: true + - name: Check formatting + # yamllint's "colored" output type is most suitable for humans reading the log. + format: colored + continue-on-error: false + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry + run: pip install poetry + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Check YAML + continue-on-error: ${{ matrix.configuration.continue-on-error }} + run: task yaml:lint YAMLLINT_FORMAT=${{ matrix.configuration.format }} diff --git a/.yamllint.yml b/.yamllint.yml new file mode 100644 index 0000000..e235f87 --- /dev/null +++ b/.yamllint.yml @@ -0,0 +1,74 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-yaml/.yamllint.yml +# See: https://yamllint.readthedocs.io/en/stable/configuration.html +# The code style defined in this file is the official standardized style to be used in all Arduino tooling projects and +# should not be modified. +# Note: Rules disabled solely because they are redundant to Prettier are marked with a "Prettier" comment. + +rules: + braces: + level: error + forbid: non-empty + min-spaces-inside: -1 # Prettier + max-spaces-inside: -1 # Prettier + min-spaces-inside-empty: -1 # Prettier + max-spaces-inside-empty: -1 # Prettier + brackets: + level: error + forbid: non-empty + min-spaces-inside: -1 # Prettier + max-spaces-inside: -1 # Prettier + min-spaces-inside-empty: -1 # Prettier + max-spaces-inside-empty: -1 # Prettier + colons: disable # Prettier + commas: disable # Prettier + comments: disable # Prettier + comments-indentation: disable # Prettier + document-end: disable # Prettier + document-start: disable + empty-lines: disable # Prettier + empty-values: disable + hyphens: disable # Prettier + indentation: disable # Prettier + key-duplicates: disable # Prettier + key-ordering: disable + line-length: + level: warning + max: 120 + allow-non-breakable-words: true + allow-non-breakable-inline-mappings: true + new-line-at-end-of-file: disable # Prettier + new-lines: disable # Prettier + octal-values: + level: warning + forbid-implicit-octal: true + forbid-explicit-octal: false + quoted-strings: disable + trailing-spaces: disable # Prettier + truthy: + level: error + allowed-values: + - "true" + - "false" + - "on" # Used by GitHub Actions as a workflow key. + check-keys: true + +yaml-files: + # Source: https://github.com/ikatyang/linguist-languages/blob/master/data/YAML.json (used by Prettier) + - ".clang-format" + - ".clang-tidy" + - ".gemrc" + - ".yamllint" + - "glide.lock" + - "*.yml" + - "*.mir" + - "*.reek" + - "*.rviz" + - "*.sublime-syntax" + - "*.syntax" + - "*.yaml" + - "*.yaml-tmlanguage" + - "*.yaml.sed" + - "*.yml.mysql" + +ignore: | + /.git/ diff --git a/Taskfile.yml b/Taskfile.yml index 67b82c1..5dd67fd 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -45,6 +45,12 @@ tasks: cmds: - npx prettier --write . + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml + poetry:install-deps: + desc: Install dependencies managed by Poetry + 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 @@ -112,3 +118,11 @@ tasks: exit 1 fi - shfmt -w . + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-yaml-task/Taskfile.yml + yaml:lint: + desc: Check for problems with YAML files + deps: + - task: poetry:install-deps + cmds: + - poetry run yamllint --format {{default "colored" .YAMLLINT_FORMAT}} . diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..8145aa8 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,72 @@ +[[package]] +name = "pathspec" +version = "0.9.0" +description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" + +[[package]] +name = "pyyaml" +version = "5.4.1" +description = "YAML parser and emitter for Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" + +[[package]] +name = "yamllint" +version = "1.26.3" +description = "A linter for YAML files." +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pathspec = ">=0.5.3" +pyyaml = "*" + +[metadata] +lock-version = "1.1" +python-versions = "^3.9" +content-hash = "525865839982686d88063539d91c35800fb198e6d6a4d610737d89c3f3dbcdc1" + +[metadata.files] +pathspec = [ + {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, + {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, +] +pyyaml = [ + {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, + {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, + {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, + {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, + {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, + {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, + {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, + {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, + {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, + {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, + {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, + {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, + {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, + {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, + {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, + {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, + {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, +] +yamllint = [ + {file = "yamllint-1.26.3.tar.gz", hash = "sha256:3934dcde484374596d6b52d8db412929a169f6d9e52e20f9ade5bf3523d9b96e"}, +] diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..ca452ee --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,15 @@ +[tool.poetry] +name = "arduinoOTA" +version = "0.0.0" +description = "" +authors = [] + +[tool.poetry.dependencies] +python = "^3.9" + +[tool.poetry.dev-dependencies] +yamllint = "^1.26.3" + +[build-system] +requires = ["poetry-core>=1.0.0"] +build-backend = "poetry.core.masonry.api" From d42bb7e29f336176336fb4dcb1c29697d404fe08 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:07:57 -0700 Subject: [PATCH 09/18] Add CI workflow to check for commonly misspelled words On every push, pull request, and periodically, use codespell to check for commonly misspelled words. In the event of a false positive, the problematic word should be added, in all lowercase, to the `ignore-words-list` field of `.codespellrc`. Regardless of the case of the word in the false positive, it must be in all lowercase in the ignore list. The ignore list is comma-separated with no spaces. --- .codespellrc | 9 ++++++ .github/workflows/spell-check-task.yml | 41 ++++++++++++++++++++++++++ Taskfile.yml | 16 ++++++++++ poetry.lock | 18 ++++++++++- pyproject.toml | 1 + 5 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 .codespellrc create mode 100644 .github/workflows/spell-check-task.yml diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 0000000..1c6b46f --- /dev/null +++ b/.codespellrc @@ -0,0 +1,9 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check/.codespellrc +# See: https://github.com/codespell-project/codespell#using-a-config-file +[codespell] +# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here: +ignore-words-list = , +skip = ./.git,./go.mod,./go.sum,./package-lock.json,./poetry.lock,./yarn.lock +builtin = clear,informal,en-GB_to_en-US +check-filenames = +check-hidden = diff --git a/.github/workflows/spell-check-task.yml b/.github/workflows/spell-check-task.yml new file mode 100644 index 0000000..3b59435 --- /dev/null +++ b/.github/workflows/spell-check-task.yml @@ -0,0 +1,41 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/spell-check-task.md +name: Spell Check + +env: + # See: https://github.com/actions/setup-python/tree/v2#available-versions-of-python + PYTHON_VERSION: "3.9" + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + push: + pull_request: + schedule: + # Run every Tuesday at 8 AM UTC to catch new misspelling detections resulting from dictionary updates. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + spellcheck: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Python + uses: actions/setup-python@v2 + with: + python-version: ${{ env.PYTHON_VERSION }} + + - name: Install Poetry + run: pip install poetry + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Spell check + run: task general:check-spelling diff --git a/Taskfile.yml b/Taskfile.yml index 5dd67fd..77908ca 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -45,6 +45,22 @@ tasks: cmds: - npx prettier --write . + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check-task/Taskfile.yml + general:check-spelling: + desc: Check for commonly misspelled words + deps: + - task: poetry:install-deps + cmds: + - poetry run codespell + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/spell-check-task/Taskfile.yml + general:correct-spelling: + desc: Correct commonly misspelled words where possible + deps: + - task: poetry:install-deps + cmds: + - poetry run codespell --write-changes + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml poetry:install-deps: desc: Install dependencies managed by Poetry diff --git a/poetry.lock b/poetry.lock index 8145aa8..4544e96 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,3 +1,15 @@ +[[package]] +name = "codespell" +version = "2.1.0" +description = "Codespell" +category = "dev" +optional = false +python-versions = ">=3.5" + +[package.extras] +dev = ["check-manifest", "flake8", "pytest", "pytest-cov", "pytest-dependency"] +hard-encoding-detection = ["chardet"] + [[package]] name = "pathspec" version = "0.9.0" @@ -29,9 +41,13 @@ pyyaml = "*" [metadata] lock-version = "1.1" python-versions = "^3.9" -content-hash = "525865839982686d88063539d91c35800fb198e6d6a4d610737d89c3f3dbcdc1" +content-hash = "3eef6d1c461ebdb2f1abc7184f0a2a686f3a81eb23793e4183ee007d1c999689" [metadata.files] +codespell = [ + {file = "codespell-2.1.0-py3-none-any.whl", hash = "sha256:b864c7d917316316ac24272ee992d7937c3519be4569209c5b60035ac5d569b5"}, + {file = "codespell-2.1.0.tar.gz", hash = "sha256:19d3fe5644fef3425777e66f225a8c82d39059dcfe9edb3349a8a2cf48383ee5"}, +] pathspec = [ {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, diff --git a/pyproject.toml b/pyproject.toml index ca452ee..e63ac37 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,6 +9,7 @@ python = "^3.9" [tool.poetry.dev-dependencies] yamllint = "^1.26.3" +codespell = "^2.1.0" [build-system] requires = ["poetry-core>=1.0.0"] From 83158798f342044588b0ea0a9e2e157b9cea990a Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:14:13 -0700 Subject: [PATCH 10/18] Add CI workflow to check Markdown files for problems On every push and pull request that affects relevant files, and periodically, check the repository's Markdown files for problems: - Use markdownlint to check for common problems and formatting. - Use markdown-link-check to check for broken links. The Arduino tooling Markdown style is defined by the `.markdownlint.yml` file. In the event the repository contains externally maintained Markdown files, markdownlint can be configured to ignore them via a `.markdownlintignore` file: https://github.com/igorshubovych/markdownlint-cli#ignoring-files markdown-link-check is configured via the `.markdown-link-check.json` file: https://github.com/tcort/markdown-link-check#config-file-format --- .github/workflows/check-markdown-task.yml | 66 +++++++++++++++++++++++ .markdown-link-check.json | 5 ++ .markdownlint.yml | 62 +++++++++++++++++++++ Taskfile.yml | 60 +++++++++++++++++++++ 4 files changed, 193 insertions(+) create mode 100644 .github/workflows/check-markdown-task.yml create mode 100644 .markdown-link-check.json create mode 100644 .markdownlint.yml diff --git a/.github/workflows/check-markdown-task.yml b/.github/workflows/check-markdown-task.yml new file mode 100644 index 0000000..1dd9350 --- /dev/null +++ b/.github/workflows/check-markdown-task.yml @@ -0,0 +1,66 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-markdown-task.md +name: Check Markdown + +# See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/check-markdown-task.ya?ml" + - ".markdown-link-check.json" + - "Taskfile.ya?ml" + - "**/.markdownlint*" + - "**.mdx?" + - "**.mkdn" + - "**.mdown" + - "**.markdown" + pull_request: + paths: + - ".github/workflows/check-markdown-task.ya?ml" + - ".markdown-link-check.json" + - "Taskfile.ya?ml" + - "**/.markdownlint*" + - "**.mdx?" + - "**.mkdn" + - "**.mdown" + - "**.markdown" + schedule: + # Run every Tuesday at 8 AM UTC to catch breakage caused by external changes. + - cron: "0 8 * * TUE" + workflow_dispatch: + repository_dispatch: + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Initialize markdownlint-cli problem matcher + uses: xt0rted/markdownlint-problem-matcher@v1 + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Lint + run: task markdown:lint + + links: + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install Task + uses: arduino/setup-task@v1 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Check links + run: task --silent markdown:check-links diff --git a/.markdown-link-check.json b/.markdown-link-check.json new file mode 100644 index 0000000..da79879 --- /dev/null +++ b/.markdown-link-check.json @@ -0,0 +1,5 @@ +{ + "retryOn429": true, + "retryCount": 3, + "aliveStatusCodes": [200, 206] +} diff --git a/.markdownlint.yml b/.markdownlint.yml new file mode 100644 index 0000000..65b6ef7 --- /dev/null +++ b/.markdownlint.yml @@ -0,0 +1,62 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-markdown/.markdownlint.yml +# See: https://github.com/DavidAnson/markdownlint/blob/main/doc/Rules.md +# The code style defined in this file is the official standardized style to be used in all Arduino projects and should +# not be modified. +# Note: Rules disabled solely because they are redundant to Prettier are marked with a "Prettier" comment. + +default: false +MD001: false +MD002: false +MD003: false # Prettier +MD004: false # Prettier +MD005: false # Prettier +MD006: false # Prettier +MD007: false # Prettier +MD008: false # Prettier +MD009: + br_spaces: 0 + strict: true + list_item_empty_lines: false # Prettier +MD010: false # Prettier +MD011: true +MD012: false # Prettier +MD013: false +MD014: false +MD018: true +MD019: false # Prettier +MD020: true +MD021: false # Prettier +MD022: false # Prettier +MD023: false # Prettier +MD024: false +MD025: + level: 1 + front_matter_title: '^\s*"?title"?\s*[:=]' +MD026: false +MD027: false # Prettier +MD028: false +MD029: + style: one +MD030: + ul_single: 1 + ol_single: 1 + ul_multi: 1 + ol_multi: 1 +MD031: false # Prettier +MD032: false # Prettier +MD033: false +MD034: false +MD035: false # Prettier +MD036: false +MD037: true +MD038: true +MD039: true +MD040: false +MD041: false +MD042: true +MD043: false +MD044: false +MD045: true +MD046: + style: fenced +MD047: false # Prettier diff --git a/Taskfile.yml b/Taskfile.yml index 77908ca..a9c77a4 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -28,6 +28,11 @@ tasks: -s "{{.WORKFLOW_SCHEMA_PATH}}" \ -d "{{.WORKFLOWS_DATA_PATH}}" + docs:generate: + desc: Create all generated documentation content + # This is an "umbrella" task used to call any documentation generation processes the project has. + # It can be left empty if there are none. + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-general-formatting-task/Taskfile.yml general:check-formatting: desc: Check basic formatting style of all files @@ -61,6 +66,61 @@ tasks: cmds: - poetry run codespell --write-changes + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-markdown-task/Taskfile.yml + markdown:check-links: + desc: Check for broken links + deps: + - task: docs:generate + cmds: + - | + if [[ "{{.OS}}" == "Windows_NT" ]]; then + # npx --call uses the native shell, which makes it too difficult to use npx for this application on Windows, + # so the Windows user is required to have markdown-link-check installed and in PATH. + if ! which markdown-link-check &>/dev/null; then + echo "markdown-link-check not found or not in PATH. Please install: https://github.com/tcort/markdown-link-check#readme" + exit 1 + fi + # Default behavior of the task on Windows is to exit the task when the first broken link causes a non-zero + # exit status, but it's better to check all links before exiting. + set +o errexit + STATUS=0 + # Using -regex instead of -name to avoid Task's behavior of globbing even when quoted on Windows + # 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. + for file in $(find . -regex ".*[.]md"); do + markdown-link-check \ + --quiet \ + --config "./.markdown-link-check.json" \ + "$file" + STATUS=$(( $STATUS + $? )) + done + exit $STATUS + else + npx --package=markdown-link-check --call=' + STATUS=0 + for file in $(find . -regex ".*[.]md"); do + markdown-link-check \ + --quiet \ + --config "./.markdown-link-check.json" \ + "$file" + STATUS=$(( $STATUS + $? )) + done + exit $STATUS + ' + fi + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-markdown-task/Taskfile.yml + markdown:fix: + desc: Automatically correct linting violations in Markdown files where possible + cmds: + - npx markdownlint-cli --fix "**/*.md" + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-markdown-task/Taskfile.yml + markdown:lint: + desc: Check for problems in Markdown files + cmds: + - npx markdownlint-cli "**/*.md" + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml poetry:install-deps: desc: Install dependencies managed by Poetry From 6b1f50340baddb44291f2485049703b0d994003e Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:16:20 -0700 Subject: [PATCH 11/18] Standardize indentation in deploy script Arduino tooling projects use two spaces for indentation in shell scripts. Previously, the script used a random mixture of three space and tab indents which didn't even match the program structure. --- deploy.sh | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/deploy.sh b/deploy.sh index 3ef79e3..de36dc4 100755 --- a/deploy.sh +++ b/deploy.sh @@ -18,10 +18,10 @@ mkdir distrib for folder in "${target_folders[@]}" do - IFS=_ read -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 + IFS=_ read -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 @@ -31,13 +31,13 @@ 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 + 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 ======= From b3f973d1afc2f254310d593946973bdbcdbe2241 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:19:45 -0700 Subject: [PATCH 12/18] Remove extra blank line from deploy script Superfluous blank lines are not permitted by the shfmt formatting tool now used to maintain consistent shell code formatting in this repository. --- deploy.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/deploy.sh b/deploy.sh index de36dc4..0b56839 100755 --- a/deploy.sh +++ b/deploy.sh @@ -46,4 +46,3 @@ echo ======= sha256sum arduinoOTA* echo ======= shasum arduinoOTA* - From 35b3bda612721042fa900ff127ec7e7ec410785f Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:31:37 -0700 Subject: [PATCH 13/18] Replace discouraged command substitution syntax in deploy script The previous backticks command substitution syntax is discouraged in favor of the modern `$()` syntax for the reasons described here: http://mywiki.wooledge.org/BashFAQ/082 --- deploy.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/deploy.sh b/deploy.sh index 0b56839..391f50c 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,9 +1,9 @@ #!/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 '"'` +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=`cat main.go| grep "const AppVersion" |cut -f4 -d " " | tr -d '"'` +VERSION="$(cat main.go| grep "const AppVersion" |cut -f4 -d " " | tr -d '"')" #Remember to set GOROOT accordingly with your installation From b63ef47d904222338eff1d5b6837d6f144749848 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:39:22 -0700 Subject: [PATCH 14/18] Protect variables from globbing and word splitting in deploy script Stinginess with quoting in shell scripts is the most common cause of confusing bugs that usually only occur under specific uncommon conditions. For this reason, all variables must be quoted. More information: https://github.com/koalaman/shellcheck/wiki/SC2086 --- deploy.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/deploy.sh b/deploy.sh index 391f50c..16cd07e 100755 --- a/deploy.sh +++ b/deploy.sh @@ -1,7 +1,7 @@ #!/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 '"')" +COMPILEINFO="$(echo "+${GIT_REV}+${BUILD_DATE}" | tr -d '"')" VERSION="$(cat main.go| grep "const AppVersion" |cut -f4 -d " " | tr -d '"')" @@ -19,9 +19,9 @@ mkdir distrib for folder in "${target_folders[@]}" do - IFS=_ read -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 + IFS=_ read -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 @@ -31,11 +31,11 @@ cd distrib for folder in "${target_folders[@]}" do - mv $folder arduinoOTA + mv "$folder" arduinoOTA if [[ $folder == "windows_386" ]]; then - zip -r arduinoOTA-$VERSION-$folder.zip arduinoOTA/ + zip -r "arduinoOTA-${VERSION}-${folder}.zip" arduinoOTA/ else - tar cjf arduinoOTA-$VERSION-$folder.tar.bz2 arduinoOTA/ + tar cjf "arduinoOTA-${VERSION}-${folder}.tar.bz2" arduinoOTA/ fi rm -rf arduinoOTA done From 162d79c164c2d70c0884d08ea81b0ce2c66dce8e Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:45:21 -0700 Subject: [PATCH 15/18] Remove unnecessary cat from version parsing command The deploy script contains a fairly complex command used to parse the code to get the current version. This command used `cat` to pipe the contents of the file to `grep`. But `grep` has a filename argument, so this was unnecessary. More information: https://github.com/koalaman/shellcheck/wiki/SC2002 --- deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy.sh b/deploy.sh index 16cd07e..0710f63 100755 --- a/deploy.sh +++ b/deploy.sh @@ -3,7 +3,7 @@ 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="$(cat main.go| grep "const AppVersion" |cut -f4 -d " " | tr -d '"')" +VERSION="$(grep "const AppVersion" main.go |cut -f4 -d " " | tr -d '"')" #Remember to set GOROOT accordingly with your installation From 2504dea0658ab85aaacc7f34fbaed16361b81944 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 19:56:21 -0700 Subject: [PATCH 16/18] Follow best practices with `read` command in deploy script The valued advice provided by the ShellCheck shell script static analysis tool is: https://github.com/koalaman/shellcheck/wiki/SC2162 > You should always use `-r` unless you have a good reason not to. In order to achieve ShellCheck compliance, it is necessary to do one of the following: - Add the `-r` flag to the `read` command. - Add a ShellCheck directive to the script to disable rule SC2162 for this line. In this particular application, `-r` is not necessary, but it also does no harm. So I think the first option is best. --- deploy.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy.sh b/deploy.sh index 0710f63..c2ac938 100755 --- a/deploy.sh +++ b/deploy.sh @@ -19,7 +19,7 @@ mkdir distrib for folder in "${target_folders[@]}" do - IFS=_ read -a fields <<< "$folder" + 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 From d8ff310d58c35cc3ca4379acb23f4c8617177bcd Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 20:03:31 -0700 Subject: [PATCH 17/18] Standardize padding style in deploy script This is the shell script code formatting style required for compliance with the shfmt formatter tool. --- deploy.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deploy.sh b/deploy.sh index c2ac938..6d9f775 100755 --- a/deploy.sh +++ b/deploy.sh @@ -3,7 +3,7 @@ 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 '"')" +VERSION="$(grep "const AppVersion" main.go | cut -f4 -d " " | tr -d '"')" #Remember to set GOROOT accordingly with your installation @@ -19,7 +19,7 @@ mkdir distrib for folder in "${target_folders[@]}" do - IFS=_ read -r -a fields <<< "$folder" + 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 From 0eccc3048e47b4afdaec7bc6e17543dfbe65e9a5 Mon Sep 17 00:00:00 2001 From: per1234 Date: Fri, 1 Oct 2021 20:04:26 -0700 Subject: [PATCH 18/18] Standardize `for` loop formatting style in deploy script This is the shell script code formatting style required for compliance with the shfmt formatter tool. --- deploy.sh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/deploy.sh b/deploy.sh index 6d9f775..1d8518e 100755 --- a/deploy.sh +++ b/deploy.sh @@ -16,8 +16,7 @@ declare -a target_folders=("linux_amd64" "linux_386" "linux_arm" "darwin_amd64" mkdir distrib -for folder in "${target_folders[@]}" -do +for folder in "${target_folders[@]}"; do IFS=_ read -r -a fields <<<"$folder" mkdir -p "distrib/${folder}/bin/" @@ -29,8 +28,7 @@ mv distrib/windows_386/bin/arduinoOTA distrib/windows_386/bin/arduinoOTA.exe cd distrib -for folder in "${target_folders[@]}" -do +for folder in "${target_folders[@]}"; do mv "$folder" arduinoOTA if [[ $folder == "windows_386" ]]; then zip -r "arduinoOTA-${VERSION}-${folder}.zip" arduinoOTA/