add dependency-update workflow template (fixes #683)#756
add dependency-update workflow template (fixes #683)#756Rimsha2535 wants to merge 5 commits intomainfrom
Conversation
|
|
||
| - name: Audit Dependencies | ||
| id: audit-dependencies | ||
| run: poetry run -- nox -s dependency:audit |
There was a problem hiding this comment.
We can ask the users of the python-toolbox what they'd prefer.
When I'd written that we perform a check by running poetry run -- nox -s dependency:audit, I had thought we could check to see if there are vulnerabilities detected or not. If there were vulnerabilities, then we'd proceed with updating the dependencies. Otherwise, we would skip the update.
One way to do this would be to check the length of the produced JSON;
# this will both print the results & output them to a json file
poetry run -- nox -s dependency:audit | tee vulnerabilities.json
LENGTH=$(jq 'length' vulnerabilities.json)
echo "count=$LENGTH" >> $GITHUB_OUTPUTIn the next step, where we run update-dependencies, we can add an if-statement
if: steps.audit-dependencies.outputs.count > 0
|
| ``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. |
There was a problem hiding this comment.
| - Audits project dependencies for known vulnerabilities, updates them with Poetry when needed, and creates a pull request if ``poetry.lock`` changes. | |
| - Audits project dependencies for known vulnerabilities, updates them with Poetry when needed, and creates a pull request if the ``poetry.lock`` was changed. |
| 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, |
There was a problem hiding this comment.
| are detected, it updates the dependencies using Poetry. When ``poetry.lock`` changes, | |
| are detected, it updates the dependencies using Poetry. When the ``poetry.lock`` is changed, |
|
|
||
| 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. |
There was a problem hiding this comment.
| it creates a pull request with the update. | |
| then it creates a pull request with the update. |
| Dependency Update | ||
| ^^^^^^^^^^^^^^^^^ | ||
|
|
||
| The ``dependency-update.yml`` workflow helps keep project dependencies up to date. |
There was a problem hiding this comment.
| The ``dependency-update.yml`` workflow helps keep project dependencies up to date. | |
| The ``dependency-update.yml`` workflow is used to resolve vulnerabilities by updating our project dependencies. |
|
|
||
| .. _ci_yml: | ||
|
|
||
| Pull Request |
There was a problem hiding this comment.
You should also add a changelog entry for this in doc/changes/unreleased.md.
You can check out doc/changes/changes_6.3.0.md for inspiration.
For adding it to the changelog:
- Add an entry under the section
Features. We tend to keep these to a short sentence description that follows the format:
#<GitHub issue number>: <Past tense verb> <clause describing the changes>
- Depending on the change, we add a longer description under
Summary. In this case, I think it's worthwhile to add a few sentences and link to the documentation . This is because the CI will change for other projects due to this.
- (special note) Currently, the anchor for the documentation you wrote doesn't exist yet on main, so it is not published to our active docs. We, however, do not verify anchors (https://github.com/exasol/python-toolbox/blob/main/doc/conf.py#L90), so I believe you can just add it like:
https://exasol.github.io/python-toolbox/main/user_guide/features/github_workflows/index.html#dependency-update
| @@ -0,0 +1,93 @@ | |||
| name: Dependency Update | |||
There was a problem hiding this comment.
We also need to add documentation to:
https://exasol.github.io/python-toolbox/main/user_guide/configuration.html
To do that, we typically create a sub-page in the relevant area. In this case, we have a nice page that we can add to:
https://exasol.github.io/python-toolbox/main/user_guide/features/github_workflows/github_project_configuration.html#
Under the section Secret, we should add the Slack token name, similar to how the PYPI_TOKEN was done. Maybe then, we should also provide a link using RST (not a hyperlink) to your Dependency Update section you wrote, but we could also leave that away.
There was a problem hiding this comment.
The Slack token name is INTEGRATION_TEAM_SECURITY_UPDATES_WEBHOOK,
and it's used for the SLACK_WEBHOOK_URL. We don't need to put SLACK_WEBHOOK_URL in the description, but it might be helpful to know that for what you're writing 😉
|
The GitHub workflow code looked good, but it's always good test, so here are those tests done via Use cases:
Example PR: Like @ckunki said, we likely need to modify this text more to tell the user what to do. But it sounds like this would be done in a later effort. |
|
|
||
| - name: Create branch | ||
| id: create-branch | ||
| if: steps.check-for-poetry-lock-changes.outputs.changed == 'true' && github.ref == 'refs/heads/main' |
There was a problem hiding this comment.
From Create Branch and down, we should adapt the if-statements.
I think it might be best if we introduced a check earlier on and set one variable for it.
Then, we don't need to do each of them in full again.
Discussion
Like I said, the default branch can differ for our projects between main and master
format('refs/heads/{0}', github.event.repository.default_branch)We mostly want to check if it's the default branch as we allow manual execution with workflow_dispatch. Perhaps in the future, we'll expand that, but we don't need that for now.
Suggested Execution Plan
- Add a step under
Check out Repositorywhere we check the default_branch. This would pass or fail and look similar to the following code. The output and such should be adapted so the default branch value is shown as well as the branch it's being executed on.
- name: Fail if not running on the default branch
id: check-branch
if: github.ref == format('refs/heads/{0}', github.event.repository.default_branch
uses: actions/github-script@v8
with:
script: |
core.setFailed('Not running on the default branch, github.ref is ${{ github.ref }}. Please start this workflow only on the default branch.')- Then, we can simplify the later if-statements by removing the branch checks for these steps:
- Create branch
- Commit changes & push
- Create pull request
|
|
||
| gh pr create \ | ||
| --base "$BASE_BRANCH" \ | ||
| --title "Update poetry.lock" \ |
There was a problem hiding this comment.
| --title "Update poetry.lock" \ | |
| --title "Update dependencies to fix vulnerabilities" \ |
There was a problem hiding this comment.
I assume the PRs to accumulate quite quick.
Should we assign a unique ID to the PR's title?
E.g.
- the date, or
- the dependencies, or vulnerabilities (probably too long and fuzzy)
There was a problem hiding this comment.
I like that idea. We could include the date, as we've also got it in the branch name
|
|
||
| This PR was created by the dependency update workflow after running: | ||
| - \`poetry run -- nox -s dependency:audit\` | ||
| - \`poetry update\`" |
| 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 |
There was a problem hiding this comment.
| 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 | |
| expected_substrings = """ | |
| build-and-publish | |
| cd | |
| check-release-tag | |
| checks | |
| ci | |
| dependency-update | |
| gh-pages | |
| matrix-all | |
| matrix-exasol | |
| matrix-python | |
| merge-gate | |
| pr-merge | |
| report | |
| slow-checks | |
| """ | |
| actual = set(result.output.split()) | |
| expected = set(expected_substrings.split()) | |
| assert expected.issubset(actual) |
| run: | | ||
| branch_name="dependency-update/$(date "+%Y%m%d%H%M%S")" | ||
| echo "Creating branch $branch_name" | ||
| git checkout -b "$branch_name" |
There was a problem hiding this comment.
| git checkout -b "$branch_name" | |
| git switch -C "$branch_name" |
Switch is recommended instead of checkout for creating and changing branches



Fixes #683
Checklist
Note: If any of the items in the checklist are not relevant to your PR, just check the box.
For any Pull Request
Is the following correct:
When Changes Were Made
Did you:
When Preparing a Release
Have you:
Notes