From fdf9333255b50435890322559603c7bda4ed5771 Mon Sep 17 00:00:00 2001 From: Rimsha Masood Date: Thu, 19 Mar 2026 14:53:36 +0100 Subject: [PATCH 1/3] added dependency-update workflow template --- .github/workflows/dependency-update.yml | 60 +++++++++++++++++++ doc/github_actions/dependency_update.rst | 14 +++++ doc/github_actions/github_actions.rst | 1 + .../github/workflows/dependency-update.yml | 60 +++++++++++++++++++ .../tools/workflow_integration_test.py | 25 +++++--- 5 files changed, 152 insertions(+), 8 deletions(-) create mode 100644 .github/workflows/dependency-update.yml create mode 100644 doc/github_actions/dependency_update.rst create mode 100644 exasol/toolbox/templates/github/workflows/dependency-update.yml diff --git a/.github/workflows/dependency-update.yml b/.github/workflows/dependency-update.yml new file mode 100644 index 000000000..69b7a1dff --- /dev/null +++ b/.github/workflows/dependency-update.yml @@ -0,0 +1,60 @@ +name: Dependency Update + +on: + schedule: + # Every Monday at 03:00 UTC + - cron: "0 3 * * 1" + workflow_dispatch: + +jobs: + dependency-update: + name: Dependency Update + runs-on: "ubuntu-24.04" + permissions: + contents: write + pull-requests: write + + steps: + - name: Check out Repository + id: check-out-repository + uses: actions/checkout@v6 + + - name: Set up Python & Poetry Environment + id: set-up-python-and-poetry-environment + uses: exasol/python-toolbox/.github/actions/python-environment@v6 + with: + python-version: "3.10" + poetry-version: "2.3.0" + + - name: Audit Dependencies + id: audit-dependencies + run: poetry run -- nox -s dependency:audit + + - name: Update Dependencies + id: update-dependencies + run: poetry update + + - name: Check for poetry.lock Changes + id: check-for-poetry-lock-changes + run: | + if git diff --quiet -- poetry.lock; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create Pull Request + id: create-pull-request + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "Update poetry.lock" + branch: dependency-update/poetry-lock + delete-branch: true + title: "Update poetry.lock" + body: |- + Automated dependency update for `poetry.lock`. + + This PR was created by the dependency update workflow after running: + - `poetry run -- nox -s dependency:audit` + - `poetry update` diff --git a/doc/github_actions/dependency_update.rst b/doc/github_actions/dependency_update.rst new file mode 100644 index 000000000..807ffeefd --- /dev/null +++ b/doc/github_actions/dependency_update.rst @@ -0,0 +1,14 @@ +dependency-update +================= + +This workflow updates the project dependencies using Poetry. + +It first runs a dependency audit via ``nox -s dependency:audit`` and then updates the dependencies using ``poetry update``. +If the ``poetry.lock`` file changes, a pull request is created automatically. + +Example Usage +------------- + +.. code-block:: bash + + tbx workflow install dependency-update \ No newline at end of file diff --git a/doc/github_actions/github_actions.rst b/doc/github_actions/github_actions.rst index e9139e886..d9798ac60 100644 --- a/doc/github_actions/github_actions.rst +++ b/doc/github_actions/github_actions.rst @@ -8,3 +8,4 @@ python_environment security_issues + dependency_update diff --git a/exasol/toolbox/templates/github/workflows/dependency-update.yml b/exasol/toolbox/templates/github/workflows/dependency-update.yml new file mode 100644 index 000000000..45f5a145f --- /dev/null +++ b/exasol/toolbox/templates/github/workflows/dependency-update.yml @@ -0,0 +1,60 @@ +name: Dependency Update + +on: + schedule: + # Every Monday at 03:00 UTC + - cron: "0 3 * * 1" + workflow_dispatch: + +jobs: + dependency-update: + name: Dependency Update + runs-on: "(( os_version ))" + permissions: + contents: write + pull-requests: write + + steps: + - name: Check out Repository + id: check-out-repository + uses: actions/checkout@v6 + + - name: Set up Python & Poetry Environment + id: set-up-python-and-poetry-environment + uses: exasol/python-toolbox/.github/actions/python-environment@v6 + with: + python-version: "(( minimum_python_version ))" + poetry-version: "(( dependency_manager_version ))" + + - name: Audit Dependencies + id: audit-dependencies + run: poetry run -- nox -s dependency:audit + + - name: Update Dependencies + id: update-dependencies + run: poetry update + + - name: Check for poetry.lock Changes + id: check-for-poetry-lock-changes + run: | + if git diff --quiet -- poetry.lock; then + echo "changed=false" >> "$GITHUB_OUTPUT" + else + echo "changed=true" >> "$GITHUB_OUTPUT" + fi + + - name: Create Pull Request + id: create-pull-request + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' + uses: peter-evans/create-pull-request@v7 + with: + commit-message: "Update poetry.lock" + branch: dependency-update/poetry-lock + delete-branch: true + title: "Update poetry.lock" + body: | + Automated dependency update for `poetry.lock`. + + This PR was created by the dependency update workflow after running: + - `poetry run -- nox -s dependency:audit` + - `poetry update` diff --git a/test/integration/tools/workflow_integration_test.py b/test/integration/tools/workflow_integration_test.py index cf85d0120..21f5eb100 100644 --- a/test/integration/tools/workflow_integration_test.py +++ b/test/integration/tools/workflow_integration_test.py @@ -18,6 +18,7 @@ def test_with_default(cli_runner): "check-release-tag\n" "checks\n" "ci\n" + "dependency-update\n" "gh-pages\n" "matrix-all\n" "matrix-exasol\n" @@ -33,14 +34,20 @@ def test_with_columns(cli_runner): result = cli_runner.invoke(CLI, ["list", "--columns"]) assert result.exit_code == 0 - assert result.output == ( - "build-and-publish cd check-release-tag checks ci " - "gh-pages\n" - "matrix-all matrix-exasol matrix-python merge-gate pr-merge " - "report \n" - "slow-checks \n" - ) - + assert "build-and-publish" in result.output + assert "cd" in result.output + assert "check-release-tag" in result.output + assert "checks" in result.output + assert "ci" in result.output + assert "dependency-update" in result.output + assert "gh-pages" in result.output + assert "matrix-all" in result.output + assert "matrix-exasol" in result.output + assert "matrix-python" in result.output + assert "merge-gate" in result.output + assert "pr-merge" in result.output + assert "report" in result.output + assert "slow-checks" in result.output def test_show_workflow(cli_runner): result = cli_runner.invoke(CLI, ["show", "checks"]) @@ -57,6 +64,7 @@ def test_show_workflow(cli_runner): "check-release-tag", "checks", "ci", + "dependency-update", "gh-pages", "matrix-all", "matrix-exasol", @@ -92,6 +100,7 @@ def test_all_workflows(cli_runner, tmp_path): "check-release-tag.yml", "checks.yml", "ci.yml", + "dependency-update.yml", "gh-pages.yml", "matrix-all.yml", "matrix-exasol.yml", From 67e8357c4484441debadc2cf5297ebdce964c207 Mon Sep 17 00:00:00 2001 From: Rimsha Masood Date: Mon, 13 Apr 2026 15:24:23 +0200 Subject: [PATCH 2/3] Add dependency-update workflow template and update tests --- .../github/workflows/dependency-update.yml | 73 ++++++++++++++----- test/integration/project-template/nox_test.py | 2 +- .../tools/workflow_integration_test.py | 1 + test/unit/nox/_workflow_test.py | 2 +- test/unit/tool_template_test.py | 3 + test/unit/util/workflows/templates_test.py | 1 + 6 files changed, 62 insertions(+), 20 deletions(-) diff --git a/exasol/toolbox/templates/github/workflows/dependency-update.yml b/exasol/toolbox/templates/github/workflows/dependency-update.yml index 45f5a145f..45244b37e 100644 --- a/exasol/toolbox/templates/github/workflows/dependency-update.yml +++ b/exasol/toolbox/templates/github/workflows/dependency-update.yml @@ -5,11 +5,12 @@ on: # Every Monday at 03:00 UTC - cron: "0 3 * * 1" workflow_dispatch: + workflow_call: jobs: dependency-update: name: Dependency Update - runs-on: "(( os_version ))" + runs-on: "ubuntu-24.04" permissions: contents: write pull-requests: write @@ -18,24 +19,33 @@ jobs: - name: Check out Repository id: check-out-repository uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Set up Python & Poetry Environment id: set-up-python-and-poetry-environment uses: exasol/python-toolbox/.github/actions/python-environment@v6 with: - python-version: "(( minimum_python_version ))" - poetry-version: "(( dependency_manager_version ))" + python-version: "3.10" + poetry-version: "2.3.0" - name: Audit Dependencies id: audit-dependencies - run: poetry run -- nox -s dependency:audit + shell: bash + run: | + poetry run -- nox -s dependency:audit | tee vulnerabilities.json + LENGTH=$(jq 'length' vulnerabilities.json) + echo "count=$LENGTH" >> "$GITHUB_OUTPUT" - name: Update Dependencies id: update-dependencies + if: steps.audit-dependencies.outputs.count > 0 run: poetry update - name: Check for poetry.lock Changes id: check-for-poetry-lock-changes + if: steps.audit-dependencies.outputs.count > 0 + shell: bash run: | if git diff --quiet -- poetry.lock; then echo "changed=false" >> "$GITHUB_OUTPUT" @@ -43,18 +53,45 @@ jobs: echo "changed=true" >> "$GITHUB_OUTPUT" fi - - name: Create Pull Request - id: create-pull-request + - name: Configure git + id: configure-git if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v7 - with: - commit-message: "Update poetry.lock" - branch: dependency-update/poetry-lock - delete-branch: true - title: "Update poetry.lock" - body: | - Automated dependency update for `poetry.lock`. - - This PR was created by the dependency update workflow after running: - - `poetry run -- nox -s dependency:audit` - - `poetry update` + shell: bash + run: | + git config --global user.email "opensource@exasol.com" + git config --global user.name "Automatic Dependency Updater" + + - name: Create branch + id: create-branch + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' + shell: bash + run: | + branch_name="dependency-update/poetry-lock" + echo "Creating branch $branch_name" + git checkout -b "$branch_name" + + - name: Commit changes & push + id: publish-branch + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && startsWith(github.ref, 'refs/heads/') + shell: bash + run: | + branch_name=$(git rev-parse --abbrev-ref HEAD) + git add poetry.lock + git commit --message "Update poetry.lock" + git push --set-upstream origin "$branch_name" + + - name: Create pull request + id: create-pr + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' + env: + GH_TOKEN: ${{ github.token }} + shell: bash + run: | + gh pr create \ + --base main \ + --title "Update poetry.lock" \ + --body "Automated dependency update for \`poetry.lock\`. + + This PR was created by the dependency update workflow after running: + - \`poetry run -- nox -s dependency:audit\` + - \`poetry update\`" diff --git a/test/integration/project-template/nox_test.py b/test/integration/project-template/nox_test.py index cc5767ad9..33c239712 100644 --- a/test/integration/project-template/nox_test.py +++ b/test/integration/project-template/nox_test.py @@ -76,4 +76,4 @@ def test_install_github_workflows(self, poetry_path, run_command): assert output.returncode == 0 file_list = run_command(["ls", ".github/workflows"]).stdout.splitlines() - assert len(file_list) == 13 + assert len(file_list) == 14 diff --git a/test/integration/tools/workflow_integration_test.py b/test/integration/tools/workflow_integration_test.py index 21f5eb100..4f8cbed7f 100644 --- a/test/integration/tools/workflow_integration_test.py +++ b/test/integration/tools/workflow_integration_test.py @@ -49,6 +49,7 @@ def test_with_columns(cli_runner): assert "report" in result.output assert "slow-checks" in result.output + def test_show_workflow(cli_runner): result = cli_runner.invoke(CLI, ["show", "checks"]) diff --git a/test/unit/nox/_workflow_test.py b/test/unit/nox/_workflow_test.py index c4a048719..a0654c93d 100644 --- a/test/unit/nox/_workflow_test.py +++ b/test/unit/nox/_workflow_test.py @@ -35,7 +35,7 @@ class TestGenerateWorkflow: @staticmethod @pytest.mark.parametrize( "nox_session_runner_posargs, expected_count", - [(ALL, 13), *[(key, 1) for key in WORKFLOW_TEMPLATE_OPTIONS.keys()]], + [(ALL, 14), *[(key, 1) for key in WORKFLOW_TEMPLATE_OPTIONS.keys()]], indirect=["nox_session_runner_posargs"], ) def test_works_as_expected( diff --git a/test/unit/tool_template_test.py b/test/unit/tool_template_test.py index 74734877d..d60c24a3d 100644 --- a/test/unit/tool_template_test.py +++ b/test/unit/tool_template_test.py @@ -11,6 +11,7 @@ def test_retrieve_workflow_templates(): "check-release-tag": "check-release-tag.yml", "checks": "checks.yml", "ci": "ci.yml", + "dependency-update": "dependency-update.yml", "gh-pages": "gh-pages.yml", "matrix-all": "matrix-all.yml", "matrix-exasol": "matrix-exasol.yml", @@ -51,6 +52,7 @@ def test_retrieve_issue_templates(): "check-release-tag": "check-release-tag.yml", "checks": "checks.yml", "ci": "ci.yml", + "dependency-update": "dependency-update.yml", "gh-pages": "gh-pages.yml", "matrix-all": "matrix-all.yml", "matrix-exasol": "matrix-exasol.yml", @@ -106,6 +108,7 @@ def test_retrieve_templates(subpackage, expected): "check-release-tag.yml", "checks.yml", "ci.yml", + "dependency-update.yml", "gh-pages.yml", "matrix-all.yml", "matrix-exasol.yml", diff --git a/test/unit/util/workflows/templates_test.py b/test/unit/util/workflows/templates_test.py index 994777e26..241796bf3 100644 --- a/test/unit/util/workflows/templates_test.py +++ b/test/unit/util/workflows/templates_test.py @@ -11,6 +11,7 @@ def test_get_workflow_templates(project_config): "check-release-tag", "checks", "ci", + "dependency-update", "gh-pages", "matrix-all", "matrix-exasol", From c9c53e6e8d1ff57ce6ba59b54cb7d364b234addd Mon Sep 17 00:00:00 2001 From: Rimsha Masood Date: Tue, 14 Apr 2026 16:19:03 +0200 Subject: [PATCH 3/3] Apply review feedback for dependency update workflow --- .github/workflows/dependency-update.yml | 63 ++++++++++++++----- doc/github_actions/dependency_update.rst | 14 ----- doc/github_actions/github_actions.rst | 1 - .../features/github_workflows/index.rst | 14 +++++ .../github/workflows/dependency-update.yml | 19 +++--- 5 files changed, 69 insertions(+), 42 deletions(-) delete mode 100644 doc/github_actions/dependency_update.rst diff --git a/.github/workflows/dependency-update.yml b/.github/workflows/dependency-update.yml index 69b7a1dff..a485ae9eb 100644 --- a/.github/workflows/dependency-update.yml +++ b/.github/workflows/dependency-update.yml @@ -5,6 +5,7 @@ on: # Every Monday at 03:00 UTC - cron: "0 3 * * 1" workflow_dispatch: + workflow_call: jobs: dependency-update: @@ -18,6 +19,8 @@ jobs: - name: Check out Repository id: check-out-repository uses: actions/checkout@v6 + with: + fetch-depth: 0 - name: Set up Python & Poetry Environment id: set-up-python-and-poetry-environment @@ -28,14 +31,19 @@ jobs: - name: Audit Dependencies id: audit-dependencies - run: poetry run -- nox -s dependency:audit + run: | + poetry run -- nox -s dependency:audit | tee vulnerabilities.json + LENGTH=$(jq 'length' vulnerabilities.json) + echo "count=$LENGTH" >> "$GITHUB_OUTPUT" - name: Update Dependencies id: update-dependencies + if: steps.audit-dependencies.outputs.count > 0 run: poetry update - name: Check for poetry.lock Changes id: check-for-poetry-lock-changes + if: steps.audit-dependencies.outputs.count > 0 run: | if git diff --quiet -- poetry.lock; then echo "changed=false" >> "$GITHUB_OUTPUT" @@ -43,18 +51,43 @@ jobs: echo "changed=true" >> "$GITHUB_OUTPUT" fi - - name: Create Pull Request - id: create-pull-request + - name: Configure git + id: configure-git if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' - uses: peter-evans/create-pull-request@v7 - with: - commit-message: "Update poetry.lock" - branch: dependency-update/poetry-lock - delete-branch: true - title: "Update poetry.lock" - body: |- - Automated dependency update for `poetry.lock`. - - This PR was created by the dependency update workflow after running: - - `poetry run -- nox -s dependency:audit` - - `poetry update` + run: | + git config --global user.email "opensource@exasol.com" + git config --global user.name "Automatic Dependency Updater" + + - name: Create branch + id: create-branch + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' + run: | + branch_name="dependency-update/$(date "+%Y%m%d%H%M%S")" + echo "Creating branch $branch_name" + git checkout -b "$branch_name" + + - name: Commit changes & push + id: publish-branch + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && startsWith(github.ref, 'refs/heads/') + run: | + branch_name=$(git rev-parse --abbrev-ref HEAD) + git add poetry.lock + git commit --message "Update poetry.lock" + git push --set-upstream origin "$branch_name" + + - name: Create pull request + id: create-pr + if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' + env: + GH_TOKEN: ${{ github.token }} + run: |- + BASE_BRANCH=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name) + + gh pr create \ + --base "$BASE_BRANCH" \ + --title "Update poetry.lock" \ + --body "Automated dependency update for \`poetry.lock\`. + + This PR was created by the dependency update workflow after running: + - \`poetry run -- nox -s dependency:audit\` + - \`poetry update\`" diff --git a/doc/github_actions/dependency_update.rst b/doc/github_actions/dependency_update.rst deleted file mode 100644 index 807ffeefd..000000000 --- a/doc/github_actions/dependency_update.rst +++ /dev/null @@ -1,14 +0,0 @@ -dependency-update -================= - -This workflow updates the project dependencies using Poetry. - -It first runs a dependency audit via ``nox -s dependency:audit`` and then updates the dependencies using ``poetry update``. -If the ``poetry.lock`` file changes, a pull request is created automatically. - -Example Usage -------------- - -.. code-block:: bash - - tbx workflow install dependency-update \ No newline at end of file diff --git a/doc/github_actions/github_actions.rst b/doc/github_actions/github_actions.rst index d9798ac60..e9139e886 100644 --- a/doc/github_actions/github_actions.rst +++ b/doc/github_actions/github_actions.rst @@ -8,4 +8,3 @@ python_environment security_issues - dependency_update diff --git a/doc/user_guide/features/github_workflows/index.rst b/doc/user_guide/features/github_workflows/index.rst index 6b6e8f7fc..b465c9610 100644 --- a/doc/user_guide/features/github_workflows/index.rst +++ b/doc/user_guide/features/github_workflows/index.rst @@ -61,6 +61,9 @@ Workflows - Pull request and monthly - Executes the continuous integration suite by calling ``merge-gate.yml`` and ``report.yml``. See :ref:`ci_yml` for a graph of workflow calls. + * - ``dependency-update.yml`` + - Weekly and manual + - Audits project dependencies for known vulnerabilities, updates them with Poetry when needed, and creates a pull request if ``poetry.lock`` changes. * - ``gh-pages.yml`` - Workflow call - Builds the documentation and deploys it to GitHub Pages. @@ -99,6 +102,17 @@ Workflows CI Actions ---------- +Dependency Update +^^^^^^^^^^^^^^^^^ + +The ``dependency-update.yml`` workflow helps keep project dependencies up to date. + +It can be triggered manually and is also scheduled to run weekly. + +The workflow first audits dependencies for known vulnerabilities. If vulnerabilities +are detected, it updates the dependencies using Poetry. When ``poetry.lock`` changes, +it creates a pull request with the update. + .. _ci_yml: Pull Request diff --git a/exasol/toolbox/templates/github/workflows/dependency-update.yml b/exasol/toolbox/templates/github/workflows/dependency-update.yml index 45244b37e..bd935cf4b 100644 --- a/exasol/toolbox/templates/github/workflows/dependency-update.yml +++ b/exasol/toolbox/templates/github/workflows/dependency-update.yml @@ -5,12 +5,11 @@ on: # Every Monday at 03:00 UTC - cron: "0 3 * * 1" workflow_dispatch: - workflow_call: jobs: dependency-update: name: Dependency Update - runs-on: "ubuntu-24.04" + runs-on: "(( os_version ))" permissions: contents: write pull-requests: write @@ -26,12 +25,11 @@ jobs: id: set-up-python-and-poetry-environment uses: exasol/python-toolbox/.github/actions/python-environment@v6 with: - python-version: "3.10" - poetry-version: "2.3.0" + python-version: "(( minimum_python_version ))" + poetry-version: "(( dependency_manager_version ))" - name: Audit Dependencies id: audit-dependencies - shell: bash run: | poetry run -- nox -s dependency:audit | tee vulnerabilities.json LENGTH=$(jq 'length' vulnerabilities.json) @@ -45,7 +43,6 @@ jobs: - name: Check for poetry.lock Changes id: check-for-poetry-lock-changes if: steps.audit-dependencies.outputs.count > 0 - shell: bash run: | if git diff --quiet -- poetry.lock; then echo "changed=false" >> "$GITHUB_OUTPUT" @@ -56,7 +53,6 @@ jobs: - name: Configure git id: configure-git if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' - shell: bash run: | git config --global user.email "opensource@exasol.com" git config --global user.name "Automatic Dependency Updater" @@ -64,16 +60,14 @@ jobs: - name: Create branch id: create-branch if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' - shell: bash run: | - branch_name="dependency-update/poetry-lock" + branch_name="dependency-update/$(date "+%Y%m%d%H%M%S")" echo "Creating branch $branch_name" git checkout -b "$branch_name" - name: Commit changes & push id: publish-branch if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && startsWith(github.ref, 'refs/heads/') - shell: bash run: | branch_name=$(git rev-parse --abbrev-ref HEAD) git add poetry.lock @@ -85,10 +79,11 @@ jobs: if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' env: GH_TOKEN: ${{ github.token }} - shell: bash run: | + BASE_BRANCH=$(gh repo view --json defaultBranchRef -q .defaultBranchRef.name) + gh pr create \ - --base main \ + --base "$BASE_BRANCH" \ --title "Update poetry.lock" \ --body "Automated dependency update for \`poetry.lock\`.