diff --git a/.env.default b/.env.default index f28208d..0c62acf 100644 --- a/.env.default +++ b/.env.default @@ -5,4 +5,4 @@ ADMIN_EMAIL="" ADMIN_FIRST_NAME="" BOT_NAME="" N8N_WEBHOOK_URL="" -WEBEX_API_KEY="" \ No newline at end of file +WEBEX_API_KEY="" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0d35f6e..55e6153 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1 @@ -* @luketainton \ No newline at end of file +* @luketainton diff --git a/.github/renovate.json b/.github/renovate.json index 67e7daa..979ffa0 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -1,47 +1,47 @@ { + "assignAutomerge": true, + "assigneesFromCodeOwners": true, + "baseBranches": [ + "main" + ], + "dependencyDashboardAutoclose": true, "extends": [ "config:base", ":semanticCommits", ":semanticCommitTypeAll(fix)" ], - "baseBranches": [ - "next" - ], - "platformCommit": true, - "dependencyDashboardAutoclose": true, - "assignAutomerge": true, - "assigneesFromCodeOwners": true, - "rebaseWhen": "behind-base-branch", - "rollbackPrs": true, "labels": [ "dependencies" ], "packageRules": [ { + "labels": [ + "linting" + ], "matchPackagePatterns": [ "black", "pylint" - ], - "labels": [ - "linting" ] }, { + "labels": [ + "unit-tests" + ], "matchPackagePatterns": [ "coverage", "pytest" - ], - "labels": [ - "unit-tests" ] } ], + "platformCommit": true, + "rebaseWhen": "behind-base-branch", + "rollbackPrs": true, "vulnerabilityAlerts": { + "commitMessagePrefix": "[SECURITY] ", "enabled": true, "labels": [ "security" ], - "commitMessagePrefix": "[SECURITY] ", "prCreation": "immediate" } -} \ No newline at end of file +} diff --git a/.github/workflows-old/release.yml b/.github/workflows-old/release.yml new file mode 100644 index 0000000..10e74be --- /dev/null +++ b/.github/workflows-old/release.yml @@ -0,0 +1,64 @@ +name: Build +on: + push: + branches: [main] + +env: + REGISTRY: ghcr.io + IMAGE_NAME: ${{ github.repository }} + +jobs: + release: + name: Release + runs-on: ubuntu-latest + outputs: + new_tag: ${{ steps.tag_version.outputs.new_tag }} + steps: + - uses: actions/checkout@v4 + - name: Bump version and push tag + id: tag_version + uses: mathieudutour/github-tag-action@v6.2 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + default_bump: minor + - name: Create a GitHub release + uses: ncipollo/release-action@v1 + with: + tag: ${{ steps.tag_version.outputs.new_tag }} + name: ${{ steps.tag_version.outputs.new_tag }} + body: ${{ steps.tag_version.outputs.changelog }} + generateReleaseNotes: true + + publish: + name: GitHub Container Registry + runs-on: ubuntu-latest + needs: release + permissions: + contents: read + packages: write + steps: + - uses: actions/checkout@v4 + - name: Login to GitHub Container Registry + run: echo ${{ secrets.GITHUB_TOKEN }} | docker login ${{ env.REGISTRY }} -u ${{ github.actor }} --password-stdin + - name: Build image for GitHub Package Registry + run: | + docker build . --file Dockerfile \ + --build-arg "version=${{ needs.release.outputs.new_tag }}" \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.release.outputs.new_tag }} \ + --tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + - name: Push image to GitHub Package Registry + run: | + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + docker push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ needs.release.outputs.new_tag }} + + # deploy: + # name: Update Portainer Deployment + # runs-on: ubuntu-latest + # needs: publish + # steps: + # - uses: fjogeleit/http-request-action@v1 + # with: + # url: ${{ secrets.PORTAINER_WEBHOOK_URL }} + # method: POST + # timeout: 60000 + # preventFailureOnNoResponse: "true" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5d728b0..6012ad1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,57 +1,18 @@ -name: Build +name: Release on: - push: - branches: [main] + workflow_dispatch: + schedule: + - cron: "0 9 * * 0" jobs: - release: - name: Release - runs-on: ubuntu-latest - outputs: - new_tag: ${{ steps.tag_version.outputs.new_tag }} - steps: - - uses: actions/checkout@v4 - - name: Bump version and push tag - id: tag_version - uses: mathieudutour/github-tag-action@v6.2 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - default_bump: minor - - name: Create a GitHub release - uses: ncipollo/release-action@v1 - with: - tag: ${{ steps.tag_version.outputs.new_tag }} - name: ${{ steps.tag_version.outputs.new_tag }} - body: ${{ steps.tag_version.outputs.changelog }} - generateReleaseNotes: true + create_release: + name: Create Release + uses: luketainton/gha-workflows/.github/workflows/create-release.yml@main - publish: - name: GitHub Container Registry - runs-on: ubuntu-latest - needs: release - steps: - - uses: actions/checkout@v4 - - name: Login to GitHub Container Registry - run: echo ${{ secrets.GHCR_ACCESS_TOKEN }} | docker login ghcr.io -u luketainton --password-stdin - - name: Build image for GitHub Package Registry - run: | - docker build . --file Dockerfile \ - --build-arg "version=${{ needs.release.outputs.new_tag }}" \ - --tag ghcr.io/luketainton/roboluke-tasks:${{ needs.release.outputs.new_tag }} \ - --tag ghcr.io/luketainton/roboluke-tasks:latest - - name: Push image to GitHub Package Registry - run: | - docker push ghcr.io/luketainton/roboluke-tasks:latest - docker push ghcr.io/luketainton/roboluke-tasks:${{ needs.release.outputs.new_tag }} - - deploy: - name: Update Portainer Deployment - runs-on: ubuntu-latest - needs: publish - steps: - - uses: fjogeleit/http-request-action@v1 - with: - url: ${{ secrets.PORTAINER_WEBHOOK_URL }} - method: POST - timeout: 60000 - preventFailureOnNoResponse: "true" + create_docker: + name: Create Docker Image + needs: create_release + if: ${{ needs.create_release.outputs.success == 'true' }} + uses: luketainton/gha-workflows/.github/workflows/build-push-attest-docker.yml@main + with: + release: ${{ needs.create_release.outputs.release_name }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..9298bce --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,60 @@ +fail_fast: false + +minimum_pre_commit_version: 3.8.0 + +default_install_hook_types: [pre-commit, commit-msg] + +default_language_version: + python: python3.11 + +repos: + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.6.0 + hooks: + - id: trailing-whitespace + - id: mixed-line-ending + - id: end-of-file-fixer + - id: requirements-txt-fixer + - id: check-yaml + - id: check-added-large-files + - id: check-ast + - id: check-docstring-first + - id: check-json + - id: check-merge-conflict + - id: check-toml + - id: check-xml + - id: detect-private-key + - id: no-commit-to-branch + - id: requirements-txt-fixer + - id: name-tests-test + args: [--pytest-test-first] + - id: pretty-format-json + args: [--autofix] + + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.5.6 + hooks: + - id: ruff-format # Run the formatter. + - id: ruff # Run the linter. + args: [--fix] + + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + + - repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.10.0 + hooks: + - id: python-use-type-annotations + + - repo: https://github.com/asottile/pyupgrade + rev: v3.17.0 + hooks: + - id: pyupgrade + + - repo: https://github.com/compilerla/conventional-pre-commit + rev: v3.4.0 + hooks: + - id: conventional-pre-commit + stages: [commit-msg] diff --git a/app/utils/datetime.py b/app/utils/datetime.py index 472371c..f645d3b 100644 --- a/app/utils/datetime.py +++ b/app/utils/datetime.py @@ -1,18 +1,18 @@ #!/usr/bin/env python3 -from zoneinfo import ZoneInfo - from datetime import datetime +from zoneinfo import ZoneInfo def timestamp_to_date(timestamp: int) -> str: """Convert timestamp to date. - + Args: timestamp (int): Timestamp to convert. - + Returns: str: Date in the format YYYY-MM-DD. """ - return datetime.fromtimestamp(timestamp=timestamp, tz=ZoneInfo("UTC")).strftime("%Y-%m-%d") - + return datetime.fromtimestamp(timestamp=timestamp, tz=ZoneInfo("UTC")).strftime( + "%Y-%m-%d" + ) diff --git a/app/utils/n8n.py b/app/utils/n8n.py index 4c0f84b..6940174 100644 --- a/app/utils/n8n.py +++ b/app/utils/n8n.py @@ -6,10 +6,10 @@ from app.utils.config import config def __n8n_post(data: dict) -> bool: """Post data to N8N webhook URL. - + Args: data (dict): Data to post to webhook URL. - + Returns: bool: True if successful, else False. """ @@ -26,13 +26,13 @@ def __n8n_post(data: dict) -> bool: def submit_task(summary, description, completion_date, requestor) -> bool: """Submit task to N8N webhook URL. - + Args: summary (str): Summary of task. description (str): Description of task. completion_date (str): Completion date of task. requestor (str): Requestor of task. - + Returns: bool: True if successful, else False. """ @@ -49,10 +49,10 @@ def submit_task(summary, description, completion_date, requestor) -> bool: def get_tasks(requestor) -> bool: """Get tasks from N8N webhook URL. - + Args: requestor (str): Requestor of tasks. - + Returns: bool: True if successful, else False. """ diff --git a/docker-compose.yml b/docker-compose.yml index ee034ed..dab1a66 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,4 +7,4 @@ services: dockerfile: Dockerfile restart: unless-stopped env_file: .env -... \ No newline at end of file +... diff --git a/requirements-dev.txt b/requirements-dev.txt index 5302a18..02acffb 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -4,3 +4,4 @@ isort pylint pylint-exit pytest +zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability diff --git a/requirements.txt b/requirements.txt index 72f38f7..7e1dda8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,47 +1,48 @@ appdirs==1.4.4 -astroid==3.2.0 -attrs==23.2.0 -autopep8==2.1.0 +astroid==3.3.2 +attrs==24.2.0 +autopep8==2.3.1 backoff==2.2.1 -certifi==2024.2.2 +certifi==2024.7.4 cfgv==3.4.0 charset-normalizer==3.3.2 click==8.1.7 coloredlogs==15.0.1 dill==0.3.8 distlib==0.3.8 -filelock==3.14.0 +filelock==3.15.4 future==1.0.0 humanfriendly==10.0 -identify==2.5.36 -idna==3.7 +identify==2.6.0 +idna==3.8 iniconfig==2.0.0 lazy-object-proxy==1.10.0 mccabe==0.7.0 mypy-extensions==1.0.0 -nodeenv==1.8.0 -packaging==24.0 +nodeenv==1.9.1 +packaging==24.1 pathspec==0.12.1 -platformdirs==4.2.1 +platformdirs==4.2.2 pluggy==1.5.0 py==1.11.0 -pycodestyle==2.11.1 -PyJWT==2.8.0 -pyparsing==3.1.2 +pycodestyle==2.12.1 +PyJWT==2.9.0 +pyparsing==3.1.4 python-dateutil==2.9.0.post0 python-dotenv==1.0.1 -PyYAML==6.0.1 -requests==2.31.0 +PyYAML==6.0.2 +requests==2.32.3 requests-toolbelt==1.0.0 -sentry-sdk==2.1.1 +sentry-sdk==2.13.0 six==1.16.0 toml==0.10.2 tomli==2.0.1 -tomlkit==0.12.5 -urllib3==2.2.1 -virtualenv==20.26.1 -webex-bot==0.5.1 +tomlkit==0.13.2 +urllib3==2.2.2 +virtualenv==20.26.3 +webex-bot==0.5.2 webexteamssdk==1.6.1 websockets==11.0.3 wrapt==1.16.0 xmltodict==0.13.0 +zipp>=3.19.1 # not directly required, pinned by Snyk to avoid a vulnerability