Update README.md

Closes #189
This commit is contained in:
alstr 2024-09-23 13:54:57 +01:00
parent 81eaa8f8e3
commit e08f24ef42
2 changed files with 240 additions and 137 deletions

377
README.md
View File

@ -1,26 +1,41 @@
# TODO to Issue Action
# TODO to Issue
This action will convert newly committed TODO comments to GitHub issues on push.
Action to create, update and close issues based on committed TODO comments.
Optionally, issues can also be closed when the TODOs are removed in a future commit.
![Diagram showing how the action works](diagram.png)
Action supports:
Features:
* Multiple, customizable comments identifiers (FIXME, etc.),
* Configurable auto-labeling,
* Assignees,
* Milestones.
* Multiple, customisable comment identifiers (`FIXME`, etc.)
* Configurable auto-labeling
* Assignees
* Milestones
* Projects
`todo-to-issue` works with almost any programming language.
## What's New
v5 is the biggest release yet:
* TODO reference handling
* Issue URL insertion
* Update and comment on existing issues
* Support for v2 projects
* Assign milestones by name
* Improved issue formatting
* Link issues to PRs
See [Upgrading](#upgrading) for breaking changes.
## Usage
Simply add a comment starting with TODO (or any other comment identifiers configured), followed by a colon and/or space.
Simply add a line or block comment starting with TODO (or any other comment identifiers configured), followed by a colon and/or space.
Here's an example for Python creating an issue named after the TODO _description_:
```python
def hello_world():
def hello_world():
# TODO Come up with a more imaginative greeting
print('Hello world!')
```
@ -28,27 +43,39 @@ Here's an example for Python creating an issue named after the TODO _description
_Multiline_ TODOs are supported, with additional lines inserted into the issue body:
```python
def hello_world():
def hello_world():
# TODO: Come up with a more imaginative greeting
# Everyone uses hello world and it's boring.
print('Hello world!')
```
As per the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#TODO_Comments), you can provide a
_reference_ after the TODO identifier. This will be included in the issue title for searchability.
As per the [Google Style Guide](https://google.github.io/styleguide/cppguide.html#TODO_Comments), you can provide a _reference_ after the TODO identifier:
```python
def hello_world():
# TODO(alstr) Come up with a more imaginative greeting
# Everyone uses hello world and it's boring.
print('Hello world!')
def hello_world():
# TODO(@alstr): Come up with a more imaginative greeting
# This will assign the issue to alstr.
print('Hello world!')
# TODO(!urgent): This is wrong
# This will add an 'urgent' label.
assert 1 + 1 == 3
# TODO(#99): We need error handling here
# This will add the comment to the existing issue 99.
greeting_time = datetime.fromisoformat(date_string)
# TODO(language): Localise this string
# This will prepend the reference to the issue title
dialogue = "TODO or not TODO, that is the question."
```
Don't include parentheses within the reference itself.
Only one reference can be provided. Should you wish to further configure the issue, you can do so via
[TODO Options](#todo-options).
## TODO Options
A range of options can also be provided to apply to the new issue.
A range of options can also be provided to apply to the issue, in addition to any reference supplied.
Options follow the `name: value` syntax.
Unless otherwise specified, options should be on their own line, below the initial TODO declaration and 'body'.
@ -58,8 +85,8 @@ Unless otherwise specified, options should be on their own line, below the initi
Comma-separated list of usernames to assign to the issue:
```python
def hello_world():
# TODO(alstr): Come up with a more imaginative greeting
def hello_world():
# TODO: Come up with a more imaginative greeting
# Everyone uses hello world and it's boring.
# assignees: alstr, bouteillerAlan, hbjydev
print('Hello world!')
@ -70,8 +97,8 @@ Comma-separated list of usernames to assign to the issue:
Comma-separated list of labels to add to the issue:
```python
def hello_world():
# TODO(alstr): Come up with a more imaginative greeting
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!')
@ -79,21 +106,19 @@ Comma-separated list of labels to add to the issue:
If any of the labels do not already exist, they will be created.
The `todo` label is automatically added to issues to help the action efficiently retrieve them in the future.
### Milestone
Milestone `ID` to assign to the issue:
Milestone name to assign to the issue:
```python
def hello_world():
# TODO(alstr): Come up with a more imaginative greeting
def hello_world():
# TODO: Come up with a more imaginative greeting
# Everyone uses hello world and it's boring.
# milestone: 1
# milestone: v3.0
print('Hello world!')
```
Only a single milestone can be specified and it must already exist.
Only a single milestone can be specified. If the milestone does not exist, it will be created.
## Supported Languages
@ -150,19 +175,16 @@ Only a single milestone can be specified and it must already exist.
- XML
- YAML
New languages can easily be added to the `syntax.json` file, used by the action to identify TODO comments.
New languages can easily be added to the `syntax.json` file used by the action to identify TODO comments.
When adding languages, follow the structure of existing entries, and use the language name defined by GitHub
in [`languages.yml`](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml).
Of course, PRs adding new languages are welcome and appreciated. Please add a test for your language in order for your
PR to be accepted. See [Contributing](#contributing--issues).
PRs adding new languages are welcome and appreciated. See [Contributing](#contributing--issues).
## Setup
On your repo go to `Settings -> Actions (General) -> Workflow permissions` and enable "Read and write permissions".
In the repo where you want the action to run, go to `Settings -> Actions (General) -> Workflow permissions` and enable
"Read and write permissions".
Create a `workflow.yml` file in your `.github/workflows` directory like:
Next, create a `workflow.yml` file in your `.github/workflows` directory:
```yml
name: "Run TODO to Issue"
@ -171,39 +193,19 @@ jobs:
build:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: "actions/checkout@v4"
- name: "TODO to Issue"
uses: "alstr/todo-to-issue-action@v4"
uses: "alstr/todo-to-issue-action@v5"
```
See [Github's workflow syntax](https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions) for
further details on this file.
### URL Insertion
The workflow file takes the following optional inputs:
The action can insert the URL for a created issue back into the associated TODO.
| Parameter | Required | Description |
|-----------------|----------|------------------------------------------------------------------------------------------------------------------------------------|
| REPO | False | The path to the repository where the action will be used, e.g., 'alstr/my-repo' (automatically set) |
| BEFORE | False | The SHA of the last pushed commit (automatically set) |
| COMMITS | False | An array of commit objects describing the pushed commits |
| DIFF_URL | False | The URL to use to get the diff (automatically set) |
| SHA | False | The SHA of the latest commit (automatically set) |
| TOKEN | False | The GitHub access token to allow us to retrieve, create and update issues (automatically set) |
| LABEL | False | The label that will be used to identify TODO comments (deprecated) |
| COMMENT_MARKER | False | The marker used to signify a line comment in your code (deprecated) |
| CLOSE_ISSUES | False | Optional input that specifies whether to attempt to close an issue when a TODO is removed |
| AUTO_P | False | For multiline TODOs, format each line as a new paragraph when creating the issue | |
| IGNORE | False | A collection of comma-delimited regular expressions that match files that should be ignored when searching for TODOs |
| AUTO_ASSIGN | False | Automatically assign new issues to the user who triggered the action |
| ACTOR | False | The username of the person who triggered the action |
| ISSUE_TEMPLATE | False | The template used to format new issues |
| IDENTIFIERS | False | List of custom identifier dictionaries of the form `[{"name": "TODO", "labels": [todo]}]` |
| GITHUB_URL | False | Base URL of GitHub API |
| ESCAPE | False | Escape all special Markdown characters |
| LANGUAGES | False | A collection of comma-delimited URLs or local paths starting from the current working directory of the action for custom languages |
| NO_STANDARD | False | Exclude loading the default 'syntax.json' and 'language.yml' files from the repository |
This allows for tighter integration between issues and TODOs, enables updating issues by editing TODOs, and improves the
accuracy of the action when closing TODOs.
These can be specified using `with` parameter in the workflow file, as below:
A new feature in v5, it is disabled by default. To enable URL insertion, some extra config is required:
```yml
name: "Run TODO to Issue"
@ -212,33 +214,54 @@ jobs:
build:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: "actions/checkout@v4"
- name: "TODO to Issue"
uses: "alstr/todo-to-issue-action@v4"
uses: "alstr/todo-to-issue-action@v5"
with:
AUTO_ASSIGN: true
INSERT_ISSUE_URLS: "true"
- name: Set Git user
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "github-actions[bot]@users.noreply.github.com"
- name: Commit and Push Changes
run: |
git add .
git commit -m "Automatically added GitHub issue links to TODOs"
git push origin main
```
### Considerations
### Projects
- TODOs are found by analysing the difference between the new commit and its previous one (i.e., the diff). That means
that if this action is implemented during development, any existing TODOs will not be detected. For them to be
detected, you would have to remove them, commit, put them back, and commit again,
or [run the action manually](#running-the-action-manually).
- Should you change the TODO text, this will currently create a new issue.
- Closing TODOs is still somewhat experimental.
You can configure the action to add newly created issues to a specified v2 project (i.e., not a classic project).
## Custom Languages
The action does not have sufficient permissions by default, so you will need to create a new Personal Access Token with
the `repo` and `project` scopes.
If you want to add or overwrite language detections that are not currently supported, you can add them manually using the `LANGUAGES` input.
Then, in your repo, go to `Settings -> Secrets and variables (Actions) -> Secrets`, and enter the value as a new
repository secret with the name `PROJECTS_SECRET`.
Just create a file that contains an array with languages, each having the following properties:
Finally, add the following to the workflow file, under `with`:
```
PROJECT: "user/alstr/test"
PROJECTS_SECRET: "${{ secrets.PROJECTS_SECRET }}"
```
| Property | Type | Description |
|------------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| language | string | The unique name of the language |
| extensions | string[] | A list of file extensions for the custom language |
| markers | object[] | A list of objects (see example below) to declare the comment markers. Make sure to escape all special Markdown characters with a double backslash. |
Where `PROJECT` is a string of the form `account_type/owner/project_name`. Valid values for `account_type` are `user` or `organization`.
All newly created issues will then be automatically added to the specified project.
### Custom Languages
If you want to add language definitions that are not currently supported, or overwrite existing ones, you can do so
using the `LANGUAGES` input.
Just create a file that contains an array of languages, each with the following properties:
| Property | Description |
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
| language | The unique name of the language |
| extensions | A list of file extensions for the custom language |
| markers | A list of objects (see example below) to declare the comment markers. Make sure to escape all special Markdown characters with a double backslash. |
For example, here is a language declaration file for Java:
@ -265,41 +288,113 @@ For example, here is a language declaration file for Java:
}
]
```
Next, add the file to the `LANGUAGES` property in your workflow YAML file. Please note that if multiple paths are provided, the last path specified will take precedence over any previous ones:
Next, add the file to the `LANGUAGES` property in your workflow file.
**Using a Local File:**
```yaml
name: "Run TODO to Issue"
on: [ "push" ]
jobs:
build:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- name: "TODO to Issue"
uses: "alstr/todo-to-issue-action@v4"
with:
LANGUAGES: "path/to/my/file.json"
```
`LANGUAGES: "path/to/my/file.json"`
**Using a File from HTTP(s):**
**Using a Remote File:**
```yaml
name: "Run TODO to Issue"
on: [ "push" ]
jobs:
build:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- name: "TODO to Issue"
uses: "alstr/todo-to-issue-action@v4"
with:
LANGUAGES: "http://myserver.com/path/to/my/file.json"
```
`LANGUAGES: "https://myserver.com/path/to/my/file.json"`
This will configure the action to use your custom language file for detecting TODO comments.
Multiple paths can be provided by entering a comma-delimited string.
### All Settings
The workflow file takes the following optional inputs, specified under the `with` parameter:
#### AUTO_ASSIGN
Automatically assign new issues to the user who triggered the action.
Default: `False`
#### AUTO_P
For multiline TODOs, format each line as a new paragraph when creating the issue.
Default: `True`
#### CLOSE_ISSUES
Whether to close an issue when a TODO is removed. If enabling this, also enabling `INSERT_ISSUE_URLS` is recommended
for improved accuracy.
Default: `False`
#### ESCAPE
Escape all special Markdown characters.
Default: `True`
#### GITHUB_URL
Base URL of GitHub API. In most cases you will not need to change this.
Default: `${{ github.api_url }}`
#### IDENTIFIERS
List of custom identifier dictionaries. Use this to add support for `FIXME` and other identifiers, and assign default
labels.
Default: `[{"name": "TODO", "labels": []}]`
#### INSERT_ISSUE_URLS
Whether to insert the URL for a new issue back into the associated TODO.
See [URL Insertion](#url-insertion).
Default: `False`
#### IGNORE
A collection of comma-delimited regular expressions that match files that should be ignored when searching for TODOs.
#### ISSUE_TEMPLATE
Custom template used to format new issues. This is a string that accepts Markdown, linebreaks and the following
placeholders:
* `{{ title }}`: issue title
* `{{ body }}`: issue body
* `{{ url }}`: URL to the line
* `{{ snippet }}`: code snippet of the relevant section
If not specified the standard template is used, containing the issue body (if a multiline TODO), URL and snippet.
#### LANGUAGES
A collection of comma-delimited URLs or local paths (starting from the current working directory of the action)
for custom languages.
See [Custom Languages](#custom-languages).
#### NO_STANDARD
Exclude loading the default `syntax.json` and `languages.yml` files.
Default: `False`
#### PROJECT
A string specifying a v2 project where issues should be added.
Use the format `account_type/owner/project_name`. Valid values for `account_type` are `user` or `organization`.
See [Projects](#projects).
#### PROJECTS_SECRET
A Personal Access Token with the `repo` and `project` scopes, required for enabling support for projects.
It should be of the form `${{ secrets.PROJECTS_SECRET }}`. Do not enter actual secret.
See [Projects](#projects).
## Running the action manually
@ -323,44 +418,57 @@ jobs:
build:
runs-on: "ubuntu-latest"
steps:
- uses: "actions/checkout@v3"
- uses: "actions/checkout@v4"
- name: "TODO to Issue"
uses: "alstr/todo-to-issue-action@master"
uses: "alstr/todo-to-issue-action@v5"
env:
MANUAL_COMMIT_REF: ${{ inputs.MANUAL_COMMIT_REF }}
MANUAL_BASE_REF: ${{ inputs.MANUAL_BASE_REF }}
```
Head to the Actions section of your repo, select the workflow and then 'Run workflow'.
Head to the actions section of your repo, select the workflow and then 'Run workflow'.
You can run the workflow for a single commit by entering the commit SHA in the first box. In this case, the action will
compare the commit to the one directly before it.
You can also compare a broader range of commits. For that, also enter the 'from'/base commit SHA in the second box.
You can also compare a broader range of commits. For that, also enter the 'from' or base commit SHA in the second box.
## Upgrading
If upgrading from v4 to v5, please note the following:
* Milestones are now specified by name, not ID.
* Support for classic projects has been removed, together with the `user_projects:` and `org_projects:` options,
and `USER_PROJECTS` and `ORG_PROJECTS` workflow settings.
* The `todo` label is no longer set on created issues.
## Troubleshooting
### No issues have been created
- Make sure your file language is in `syntax.json`.
- The action will not recognise existing TODOs that have already been pushed, unless
you [run the action manually](#running-the-action-manually).
- If a similar TODO appears in the diff as both an addition and deletion, it is assumed to have been moved, so is
ignored.
- If your workflow is executed but no issue is generated, check your repo permissions by navigating
to `Settings -> Actions (General) -> Workflow permissions` and enable "Read and write permissions".
- TODOs are found by analysing the difference between the new commit and its previous one (i.e., the diff). This means
that if this action is implemented during development, any existing TODOs will not be detected. For them to be
detected, you would have to re-commit them, or [run the action manually](#running-the-action-manually).
- If your workflow is executed but no issue is generated, check your repo permissions by navigating to
`Settings -> Actions (General) -> Workflow permissions` and enable "Read and write permissions".
### Multiple issues have been created
Issues are created whenever the action runs and finds a newly added TODO in the diff. Rebasing may cause a TODO to show
up in a diff multiple times. This is an acknowledged issue, but you may have some luck by adjusting your workflow file.
Issues are created whenever the action runs and finds a newly added TODO in the diff. This can lead to duplicate
issues if a diff is processed multiple times.
Enabling [URL Insertion](#url-insertion) can help with the detection of existing issues.
## Contributing & Issues
If you do encounter any problems, please file an issue or submit a PR. Everyone is welcome and encouraged to contribute.
If encounter any problems, please file an issue or submit a PR. Everyone is welcome and encouraged to contribute.
**If submitting a request to add a new language, please ensure you add the appropriate tests covering your language. In
the interests of stability, PRs without tests cannot be considered.**
**If submitting a request to add a new language, please ensure you add the appropriate tests covering your language.
In the interests of stability, PRs without tests cannot be considered.**
When adding languages, follow the structure of existing entries, and use the language name defined by
[GitHub's `languages.yml`](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file.
## Running tests locally
@ -381,15 +489,10 @@ run:
## Thanks
The action was developed for the GitHub Hackathon. Whilst every effort is made to ensure it works, it comes with no
guarantee.
The action was originally developed for the GitHub Hackathon in 2020. Whilst every effort is made to ensure it works,
it comes with no guarantee.
Thanks to Jacob Tomlinson
for [his handy overview of GitHub Actions](https://www.jacobtomlinson.co.uk/posts/2019/creating-github-actions-in-python/).
Thanks to GitHub's [linguist repo](https://github.com/github/linguist/) for the [`languages.yml`](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file used by the app to look up file extensions
and determine the correct highlighting to apply to code snippets.
Thanks to GitHub's [linguist repo](https://github.com/github/linguist/) for
the [`languages.yml`](https://raw.githubusercontent.com/github/linguist/master/lib/linguist/languages.yml) file used by
the app to look up file extensions and determine the correct highlighting to apply to code snippets.
Thanks to all those who have [contributed](https://github.com/alstr/todo-to-issue-action/graphs/contributors) to the
further development of this action.
Thanks to all those who have [contributed](https://github.com/alstr/todo-to-issue-action/graphs/contributors) to the further development of this action.

BIN
diagram.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 301 KiB