mirror of
https://github.com/ditkrg/todo-to-issue-action.git
synced 2026-01-25 15:22:59 +00:00
Add option to disable closing issues
This commit is contained in:
32
README.md
32
README.md
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
This action will convert your `# TODO` comments to GitHub issues when a new commit is pushed.
|
This action will convert your `# TODO` comments to GitHub issues when a new commit is pushed.
|
||||||
|
|
||||||
The new issue will contain a link to the line in the file containing the TODO, together with a code snippet. The action performs a `GET` request to retrieve GitHub's [`languages.yml` file](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file to apply highlighting to the snippet.
|
The new issue will contain a link to the line in the file containing the TODO, together with a code snippet and any defined labels. The action performs a `GET` request to retrieve GitHub's [`languages.yml` file](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file to apply highlighting to the snippet.
|
||||||
|
|
||||||
It will also close an issue when a `# TODO` is removed in a pushed commit. A comment will be posted
|
It will also close an issue when a `# TODO` is removed in a pushed commit. A comment will be posted
|
||||||
with the ref of the commit that it was closed by.
|
with the ref of the commit that it was closed by.
|
||||||
@@ -16,6 +16,7 @@ The `# TODO` comment is commonly used in Python, but this can be customised to w
|
|||||||
- [Examples](#examples)
|
- [Examples](#examples)
|
||||||
- [Adding TODOs](#adding-todos)
|
- [Adding TODOs](#adding-todos)
|
||||||
- [Multiline TODOs](#multiline-todos)
|
- [Multiline TODOs](#multiline-todos)
|
||||||
|
- [Dynamic Labels](#dynamic-labels)
|
||||||
- [Removing TODOs](#removing-todos)
|
- [Removing TODOs](#removing-todos)
|
||||||
- [Updating TODOs](#updating-todos)
|
- [Updating TODOs](#updating-todos)
|
||||||
- [Existing TODOs](#existing-todos)
|
- [Existing TODOs](#existing-todos)
|
||||||
@@ -28,7 +29,7 @@ Create a workflow file in your .github/workflows directory as follows:
|
|||||||
|
|
||||||
### workflow.yaml
|
### workflow.yaml
|
||||||
|
|
||||||
Latest version is `v1.3-beta`.
|
Latest version is `v2.0`.
|
||||||
|
|
||||||
name: "Workflow"
|
name: "Workflow"
|
||||||
on: ["push"]
|
on: ["push"]
|
||||||
@@ -38,7 +39,7 @@ Latest version is `v1.3-beta`.
|
|||||||
steps:
|
steps:
|
||||||
- uses: "actions/checkout@master"
|
- uses: "actions/checkout@master"
|
||||||
- name: "TODO to Issue"
|
- name: "TODO to Issue"
|
||||||
uses: "alstr/todo-to-issue-action@v1.3-beta"
|
uses: "alstr/todo-to-issue-action@v2.0"
|
||||||
with:
|
with:
|
||||||
REPO: ${{ github.repository }}
|
REPO: ${{ github.repository }}
|
||||||
BEFORE: ${{ github.event.before }}
|
BEFORE: ${{ github.event.before }}
|
||||||
@@ -58,8 +59,9 @@ Latest version is `v1.3-beta`.
|
|||||||
| `BEFORE` | The SHA of the last pushed commit (automatically set) |
|
| `BEFORE` | The SHA of the last pushed commit (automatically set) |
|
||||||
| `SHA` | The SHA of the latest commit (automatically set) |
|
| `SHA` | The SHA of the latest commit (automatically set) |
|
||||||
| `TOKEN` | The GitHub access token to allow us to retrieve, create and update issues (automatically set) |
|
| `TOKEN` | The GitHub access token to allow us to retrieve, create and update issues (automatically set) |
|
||||||
| `LABEL` | The label that will be used to identify TODO comments (by default this is `# TODO` for Python) |
|
| `LABEL` | The label that will be used to identify TODO comments (e.g. `# TODO` for Python) |
|
||||||
| `COMMENT_MARKER` | The marker used to signify a line comment in your code (by default this is `#` for Python) |
|
| `COMMENT_MARKER` | The marker used to signify a line comment in your code (e.g. `#` for Python) |
|
||||||
|
| `CLOSE_ISSUES` | Optional input that specifies whether to attempt to close an issue when a TODO is removed (default: "true") |
|
||||||
|
|
||||||
## Examples
|
## Examples
|
||||||
|
|
||||||
@@ -92,12 +94,30 @@ The extra line(s) will be posted in the body of the issue.
|
|||||||
|
|
||||||
The `COMMENT_MARKER` input must be set to the correct syntax (e.g. `#` for Python).
|
The `COMMENT_MARKER` input must be set to the correct syntax (e.g. `#` for Python).
|
||||||
|
|
||||||
|
### Dynamic Labels
|
||||||
|
|
||||||
|
def hello_world():
|
||||||
|
# TODO Come up with a more imaginative greeting
|
||||||
|
# Everyone uses hello world and it's boring.
|
||||||
|
# labels: enhancement, help_wanted
|
||||||
|
print('Hello world!')
|
||||||
|
|
||||||
|
You can specify the labels to add to your issue in the TODO body.
|
||||||
|
|
||||||
|
The labels should be on their own line below the initial TODO declaration.
|
||||||
|
|
||||||
|
Include the `labels:` prefix, then a list of comma-separated label titles.
|
||||||
|
|
||||||
|
The `todo` label is automatically added to issues to help the action efficiently retrieve them in the future.
|
||||||
|
|
||||||
### Removing TODOs
|
### Removing TODOs
|
||||||
|
|
||||||
def hello_world():
|
def hello_world():
|
||||||
print('Hello world!')
|
print('Hello world!')
|
||||||
|
|
||||||
Removing the `# TODO` comment will close the issue on push. This is still an experimental feature.
|
Removing the `# TODO` comment will close the issue on push.
|
||||||
|
|
||||||
|
This is still an experimental feature. By default it is enabled, but if you want to disable it, you can set `CLOSE_ISSUES` to `false` as described in [workflow.yaml](#workflowyaml).
|
||||||
|
|
||||||
### Updating TODOs
|
### Updating TODOs
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,11 @@ inputs:
|
|||||||
description: "The GitHub access token to allow us to retrieve, create and update issues (automatically set)"
|
description: "The GitHub access token to allow us to retrieve, create and update issues (automatically set)"
|
||||||
required: true
|
required: true
|
||||||
LABEL:
|
LABEL:
|
||||||
description: "The label that will be used to identify TODO comments (by default this is # TODO for Python)"
|
description: "The label that will be used to identify TODO comments (e.g. # TODO for Python)"
|
||||||
required: true
|
required: true
|
||||||
COMMENT_MARKER:
|
COMMENT_MARKER:
|
||||||
description: "The marker used to signify a line comment in your code (by default this is # for Python)"
|
description: "The marker used to signify a line comment in your code (e.g. # for Python)"
|
||||||
required: true
|
required: true
|
||||||
|
CLOSE_ISSUES:
|
||||||
|
description: "Optional input that specifies whether to attempt to close an issue when a TODO is removed (default: true)"
|
||||||
|
required: false
|
||||||
|
|||||||
70
main.py
70
main.py
@@ -20,6 +20,7 @@ def main():
|
|||||||
comment_marker = os.getenv('INPUT_COMMENT_MARKER')
|
comment_marker = os.getenv('INPUT_COMMENT_MARKER')
|
||||||
label = os.getenv('INPUT_LABEL')
|
label = os.getenv('INPUT_LABEL')
|
||||||
token = os.getenv('INPUT_TOKEN')
|
token = os.getenv('INPUT_TOKEN')
|
||||||
|
close_issues = os.getenv('INPUT_CLOSE_ISSUES', 'true') == 'true'
|
||||||
|
|
||||||
# Load a file so we can see what language each file is written in and apply highlighting later.
|
# Load a file so we can see what language each file is written in and apply highlighting later.
|
||||||
languages_url = 'https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml'
|
languages_url = 'https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml'
|
||||||
@@ -225,41 +226,42 @@ def main():
|
|||||||
sleep(1)
|
sleep(1)
|
||||||
print('Creating issues complete')
|
print('Creating issues complete')
|
||||||
|
|
||||||
# Close issues for removed TODOs.
|
# Close issues for removed TODOs if this is enabled.
|
||||||
print('Start closing issues')
|
if close_issues:
|
||||||
for i, closed_issue in enumerate(closed_issues):
|
print('Start closing issues')
|
||||||
title = closed_issue
|
for i, closed_issue in enumerate(closed_issues):
|
||||||
matched = 0
|
title = closed_issue
|
||||||
issue_number = None
|
matched = 0
|
||||||
# Compare the title of each closed issue with each issue in the issues list.
|
issue_number = None
|
||||||
for current_issue in current_issues:
|
# Compare the title of each closed issue with each issue in the issues list.
|
||||||
if current_issue['body'].startswith(title):
|
for current_issue in current_issues:
|
||||||
matched += 1
|
if current_issue['body'].startswith(title):
|
||||||
# If there are multiple issues with similar titles, don't try and close any.
|
matched += 1
|
||||||
if matched > 1:
|
# If there are multiple issues with similar titles, don't try and close any.
|
||||||
print(f'Skipping issue {i + 1} of {len(closed_issues)} (multiple matches)')
|
if matched > 1:
|
||||||
break
|
print(f'Skipping issue {i + 1} of {len(closed_issues)} (multiple matches)')
|
||||||
issue_number = current_issue['number']
|
break
|
||||||
else:
|
issue_number = current_issue['number']
|
||||||
if issue_number is None:
|
|
||||||
continue
|
|
||||||
# The titles match, so we will try and close the issue.
|
|
||||||
update_issue_url = f'{base_url}{repo}/issues/{issue_number}'
|
|
||||||
body = {'state': 'closed'}
|
|
||||||
requests.patch(update_issue_url, headers=issue_headers, data=json.dumps(body))
|
|
||||||
|
|
||||||
issue_comment_url = f'{base_url}{repo}/issues/{issue_number}/comments'
|
|
||||||
body = {'body': f'Closed in {sha}'}
|
|
||||||
update_issue_request = requests.post(issue_comment_url, headers=issue_headers,
|
|
||||||
data=json.dumps(body))
|
|
||||||
print(f'Closing issue {i + 1} of {len(closed_issues)}')
|
|
||||||
if update_issue_request.status_code == 201:
|
|
||||||
print('Issue closed')
|
|
||||||
else:
|
else:
|
||||||
print('Issue could not be closed')
|
if issue_number is None:
|
||||||
# Don't update too many issues too quickly.
|
continue
|
||||||
sleep(1)
|
# The titles match, so we will try and close the issue.
|
||||||
print('Closing issues complete')
|
update_issue_url = f'{base_url}{repo}/issues/{issue_number}'
|
||||||
|
body = {'state': 'closed'}
|
||||||
|
requests.patch(update_issue_url, headers=issue_headers, data=json.dumps(body))
|
||||||
|
|
||||||
|
issue_comment_url = f'{base_url}{repo}/issues/{issue_number}/comments'
|
||||||
|
body = {'body': f'Closed in {sha}'}
|
||||||
|
update_issue_request = requests.post(issue_comment_url, headers=issue_headers,
|
||||||
|
data=json.dumps(body))
|
||||||
|
print(f'Closing issue {i + 1} of {len(closed_issues)}')
|
||||||
|
if update_issue_request.status_code == 201:
|
||||||
|
print('Issue closed')
|
||||||
|
else:
|
||||||
|
print('Issue could not be closed')
|
||||||
|
# Don't update too many issues too quickly.
|
||||||
|
sleep(1)
|
||||||
|
print('Closing issues complete')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
Reference in New Issue
Block a user