diff --git a/.github/workflows/check-poetry-task.yml b/.github/workflows/check-poetry-task.yml new file mode 100644 index 00000000..1113876e --- /dev/null +++ b/.github/workflows/check-poetry-task.yml @@ -0,0 +1,110 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-poetry-task.md +name: Check Poetry + +on: + create: + push: + paths: + - ".github/workflows/check-poetry-task.ya?ml" + - "poetry.lock" + - "pyproject.toml" + - "Taskfile.ya?ml" + pull_request: + paths: + - ".github/workflows/check-poetry-task.ya?ml" + - "poetry.lock" + - "pyproject.toml" + - "Taskfile.ya?ml" + schedule: + # Run periodically to catch breakage caused by external changes. + - cron: "0 11 * * THU" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + permissions: {} + 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/((v[0-9]+)|([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 "result=$RESULT" >> $GITHUB_OUTPUT + + validate: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version-file: pyproject.toml + + - name: Install Task + uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Validate configuration + run: | + task \ + --silent \ + poetry:validate + + check-sync: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version-file: pyproject.toml + + - name: Install Task + uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Sync lockfile + run: | + task \ + --silent \ + poetry:sync + + - name: Check if lockfile was out of sync + run: | + git diff \ + --color \ + --exit-code \ + poetry.lock diff --git a/README.md b/README.md index e0c42441..98e72b5e 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ [![Check Community Health Files Sync status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-community-health-sync.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-community-health-sync.yml) [![Check Configuration Files Sync status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-config-sync.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-config-sync.yml) [![Check Markdown status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-markdown-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-markdown-task.yml) +[![Check Poetry status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-poetry-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-poetry-task.yml) [![Check Prettier Formatting status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-prettier-formatting-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-prettier-formatting-task.yml) [![Check Taskfiles status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-taskfiles.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-taskfiles.yml) [![Check YAML status](https://github.com/arduino/tooling-project-assets/actions/workflows/check-yaml-task.yml/badge.svg)](https://github.com/arduino/tooling-project-assets/actions/workflows/check-yaml-task.yml) diff --git a/Taskfile.yml b/Taskfile.yml index ded1df3a..118843bf 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -29,6 +29,7 @@ tasks: - task: markdown:check-links - task: markdown:lint - task: markdownlint:validate + - task: poetry:validate - task: python:lint - task: python:test - task: shell:check @@ -50,6 +51,7 @@ tasks: - task: js:fix - task: markdown:fix - task: npm:fix-config + - task: poetry:sync - task: python:format - task: shell:format vars: @@ -67,6 +69,7 @@ tasks: "{{.WORKFLOW_TEMPLATES_PATH}}/check-javascript-task.yml" \ "{{.WORKFLOW_TEMPLATES_PATH}}/check-markdown-task.yml" \ "{{.WORKFLOW_TEMPLATES_PATH}}/check-npm-task.yml" \ + "{{.WORKFLOW_TEMPLATES_PATH}}/check-poetry-task.yml" \ "{{.WORKFLOW_TEMPLATES_PATH}}/check-prettier-formatting-task.yml" \ "{{.WORKFLOW_TEMPLATES_PATH}}/check-python-task.yml" \ "{{.WORKFLOW_TEMPLATES_PATH}}/check-taskfiles.yml" \ @@ -897,6 +900,16 @@ tasks: poetry install \ {{if .POETRY_GROUPS}} --only {{.POETRY_GROUPS}} {{end}} + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-poetry-task/Taskfile.yml + poetry:sync: + desc: Sync Poetry lockfile + deps: + - task: poetry:install + cmds: + - | + poetry lock \ + --no-cache + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/poetry-task/Taskfile.yml poetry:update-deps: desc: Update all dependencies managed by Poetry to their newest versions @@ -905,6 +918,17 @@ tasks: cmds: - poetry update + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-poetry-task/Taskfile.yml + poetry:validate: + desc: Validate Poetry configuration + deps: + - task: poetry:install + cmds: + - | + poetry check \ + --lock \ + --strict + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-python-task/Taskfile.yml python:format: desc: Format Python files diff --git a/poetry.lock b/poetry.lock index ae1b9f7b..b6de210f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "anyio" @@ -1837,4 +1837,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.1" python-versions = "~3.9" -content-hash = "895e971e312378fd1b1284b250201c2aebb4a0e58a6fc3806f8df2eed55c5fd5" +content-hash = "543369115838ff2f1c7c1b58f5e0335baaa51cc1b562a83ef34a36f17c8b2007" diff --git a/pyproject.toml b/pyproject.toml index 9ce3d405..96f34503 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ package-mode = false [tool.poetry.dependencies] python = "~3.9" -[tool.poetry.dev-dependencies] +[tool.poetry.group.dev.dependencies] yamllint = "^v1.37.1" codespell = "^2.4.1" black = "^25.1" diff --git a/workflow-templates/assets/check-poetry-task/Taskfile.yml b/workflow-templates/assets/check-poetry-task/Taskfile.yml new file mode 100644 index 00000000..69b434e3 --- /dev/null +++ b/workflow-templates/assets/check-poetry-task/Taskfile.yml @@ -0,0 +1,24 @@ +# See: https://taskfile.dev/#/usage +version: "3" + +tasks: + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-poetry-task/Taskfile.yml + poetry:sync: + desc: Sync Poetry lockfile + deps: + - task: poetry:install + cmds: + - | + poetry lock \ + --no-cache + + # Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/assets/check-poetry-task/Taskfile.yml + poetry:validate: + desc: Validate Poetry configuration + deps: + - task: poetry:install + cmds: + - | + poetry check \ + --lock \ + --strict diff --git a/workflow-templates/check-poetry-task.md b/workflow-templates/check-poetry-task.md new file mode 100644 index 00000000..5dad1d7e --- /dev/null +++ b/workflow-templates/check-poetry-task.md @@ -0,0 +1,72 @@ +# "Check Poetry" workflow (Task) + +Check for problems with configuration files of the [**Poetry**](https://python-poetry.org/) Python package manager. + +This is the version of the workflow for projects using the [Task](https://taskfile.dev/#/) task runner tool. + +## Installation + +### Workflow + +Install the [check-poetry-task.yml](check-poetry-task.yml) GitHub Actions workflow to `.github/workflows/` + +### Assets + +- [`Taskfile.yml`](assets/check-poetry-task/Taskfile.yml) - Validation tasks. + - Install to: repository root (or merge into the existing `Taskfile.yml`). +- [`Taskfile.yml`](assets/poetry-task/Taskfile.yml) - Installation task. + - Merge into `Taskfile.yml` + +## Readme badge + +Markdown badge: + +```markdown +[![Check Poetry status](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/check-poetry-task.yml/badge.svg)](https://github.com/REPO_OWNER/REPO_NAME/actions/workflows/check-poetry-task.yml) +``` + +Replace the `REPO_OWNER` and `REPO_NAME` placeholders in the URLs with the final repository owner and name ([example](https://raw.githubusercontent.com/arduino-libraries/ArduinoIoTCloud/master/README.md)). + +--- + +Asciidoc badge: + +```adoc +image:https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-poetry-task.yml/badge.svg["Check YAML status", link="https://github.com/{repository-owner}/{repository-name}/actions/workflows/check-poetry-task.yml"] +``` + +Define the `{repository-owner}` and `{repository-name}` attributes and use them throughout the readme ([example](https://raw.githubusercontent.com/arduino-libraries/WiFiNINA/master/README.adoc)). + +## Commit message + +``` +Add infrastructure for checking Poetry configuration files + +The project's Python package dependencies are managed using the "Poetry" tool. + +Tasks and a GitHub Actions workflow are added to maintain and check for problems in the Poetry configuration files. + +The tasks provide the following operations: + +* Check for problems with the data structure of the `pyproject.toml` Python project file +* Update the `poetry.lock` file as may be required following manual modifications to `pyproject.toml`, or update of the + "Poetry" application + +These tasks are executed by the GitHub Actions workflow on any push or pull request that modifies relevant files, and +periodically to check for breakage caused by external changes. +``` + +## PR message + +```markdown +The project's Python package dependencies are managed using the [**Poetry**](https://python-poetry.org/) tool. + +[Tasks](https://taskfile.dev/) and a GitHub Actions workflow are added to maintain and check for problems in the **Poetry** configuration files. + +The tasks provide the following operations: + +- Check for problems with the data structure of the [`pyproject.toml`](https://python-poetry.org/docs/pyproject/) Python project file +- Update the `poetry.lock` file as may be required following manual modifications to `pyproject.toml`, or update of the **Poetry** application + +These tasks are executed by the GitHub Actions workflow on any push or pull request that modifies relevant files, and periodically to check for breakage caused by external changes. +``` diff --git a/workflow-templates/check-poetry-task.yml b/workflow-templates/check-poetry-task.yml new file mode 100644 index 00000000..1113876e --- /dev/null +++ b/workflow-templates/check-poetry-task.yml @@ -0,0 +1,110 @@ +# Source: https://github.com/arduino/tooling-project-assets/blob/main/workflow-templates/check-poetry-task.md +name: Check Poetry + +on: + create: + push: + paths: + - ".github/workflows/check-poetry-task.ya?ml" + - "poetry.lock" + - "pyproject.toml" + - "Taskfile.ya?ml" + pull_request: + paths: + - ".github/workflows/check-poetry-task.ya?ml" + - "poetry.lock" + - "pyproject.toml" + - "Taskfile.ya?ml" + schedule: + # Run periodically to catch breakage caused by external changes. + - cron: "0 11 * * THU" + workflow_dispatch: + repository_dispatch: + +jobs: + run-determination: + runs-on: ubuntu-latest + permissions: {} + 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/((v[0-9]+)|([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 "result=$RESULT" >> $GITHUB_OUTPUT + + validate: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version-file: pyproject.toml + + - name: Install Task + uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Validate configuration + run: | + task \ + --silent \ + poetry:validate + + check-sync: + needs: run-determination + if: needs.run-determination.outputs.result == 'true' + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install Python + uses: actions/setup-python@v5 + with: + python-version-file: pyproject.toml + + - name: Install Task + uses: arduino/setup-task@v2 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + version: 3.x + + - name: Sync lockfile + run: | + task \ + --silent \ + poetry:sync + + - name: Check if lockfile was out of sync + run: | + git diff \ + --color \ + --exit-code \ + poetry.lock