From b9bedbe68bbbbcb707936d6446597f4709b40e2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Janek=20Nouvertn=C3=A9?= Date: Mon, 15 Jan 2024 20:40:41 +0100 Subject: [PATCH] ci: Add workflow to notify issues for released fixes (#2988) * Add workflow to notify issues for released fixes --- .github/workflows/notify-released-issues.yml | 32 ++++++++++++++++ .../get_closed_issues.py | 38 +++++++++++++++++++ .../notify_released_issues/notify.js | 34 +++++++++++++++++ .github/workflows/publish.yml | 6 +++ .pre-commit-config.yaml | 2 +- 5 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/notify-released-issues.yml create mode 100644 .github/workflows/notify_released_issues/get_closed_issues.py create mode 100644 .github/workflows/notify_released_issues/notify.js diff --git a/.github/workflows/notify-released-issues.yml b/.github/workflows/notify-released-issues.yml new file mode 100644 index 0000000000..07087c4308 --- /dev/null +++ b/.github/workflows/notify-released-issues.yml @@ -0,0 +1,32 @@ +name: Notify released issues +on: + workflow_call: + inputs: + release_tag: + type: string + required: true + +jobs: + notify: + runs-on: ubuntu-latest + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: Get released issues + id: get-released-issues + run: + echo "issues=$(python ./.github/workflows/notify_released_issues/get_closed_issues.py ${{ inputs.release_tag }})" >> "$GITHUB_OUTPUT" + + - uses: actions/github-script@v7 + env: + CLOSED_ISSUES: ${{ steps.get-released-issues.outputs.issues }} + with: + script: | + const script = require('./.github/workflows/notify_released_issues/notify.js') + await script({github, context, core}) diff --git a/.github/workflows/notify_released_issues/get_closed_issues.py b/.github/workflows/notify_released_issues/get_closed_issues.py new file mode 100644 index 0000000000..d1c3008e08 --- /dev/null +++ b/.github/workflows/notify_released_issues/get_closed_issues.py @@ -0,0 +1,38 @@ +from __future__ import annotations + +import itertools +import json +import pathlib +import re +import sys + +__all__ = ( + "find_resolved_issues", + "main", +) + + +def find_resolved_issues(source: str, tag: str) -> list[str]: + version = tag.split("v", maxsplit=1)[-1] + changelog_line = f".. changelog:: {version}" + stop_line = ".. changelog::" + return list( + { + issue + for line in itertools.takewhile( + lambda l: stop_line not in l, # noqa: E741 + source.split(changelog_line, maxsplit=1)[1].splitlines(), + ) + if re.match(r"\s+:issue: [\d ,]+", line) + for issue in re.findall(r"\d+", line) + } + ) + + +def main(tag: str) -> str: + source = pathlib.Path("docs/release-notes/changelog.rst").read_text() + return json.dumps(find_resolved_issues(source, tag)) + + +if __name__ == "__main__": + print(main(sys.argv[1])) # noqa: T201 diff --git a/.github/workflows/notify_released_issues/notify.js b/.github/workflows/notify_released_issues/notify.js new file mode 100644 index 0000000000..4e2598f750 --- /dev/null +++ b/.github/workflows/notify_released_issues/notify.js @@ -0,0 +1,34 @@ +module.exports = async ({github, context, core}) => { + + const issues = JSON.parse(process.env.CLOSED_ISSUES) + const releaseURL = context.payload.release.url + const releaseName = context.payload.release.name + const baseBody = "A fix for this issue has been released in" + const body = baseBody + ` [${releaseName}](${releaseURL})` + + for (const issueNumber of issues) { + const opts = github.rest.issues.listComments.endpoint.merge({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + }); + + const comments = await github.paginate(opts) + for (const comment of comments) { + if (comment.user.id === 41898282 && comment.body.startsWith(baseBody)) { + await github.rest.issues.deleteComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: comment.id + }) + } + } + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issueNumber, + body: body, + }) + } +} diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f41242079b..ebb4966dd3 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -97,3 +97,9 @@ jobs: - name: Publish package distributions to PyPI uses: pypa/gh-action-pypi-publish@release/v1 + + notify-issues: + name: Notify issues + uses: ./.github/workflows/notify-released-issues.yml + with: + release_tag: ${{ github.event.release.tag_name }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9cab32e2d1..262b60ef72 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -54,7 +54,7 @@ repos: rev: v0.17.1 hooks: - id: slotscheck - exclude: "test_*|docs" + exclude: "test_*|docs|.github" - repo: https://github.com/sphinx-contrib/sphinx-lint rev: "v0.9.1" hooks: