mirror of
https://github.com/zoriya/octokit.net.git
synced 2026-06-03 19:11:30 +00:00
Merge pull request #718 from octokit/null-issue-update-its-a-thing
actually fix regression with updating issue labels
This commit is contained in:
@@ -273,6 +273,84 @@ public class IssuesClientTests : IDisposable
|
||||
Assert.Null(updatedIssue.Milestone);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task DoesNotChangeLabelsByDefault()
|
||||
{
|
||||
var owner = _repository.Owner.Login;
|
||||
|
||||
await _issuesClient.Labels.Create(owner, _repository.Name, new NewLabel("something", "FF0000"));
|
||||
|
||||
var newIssue = new NewIssue("A test issue1")
|
||||
{
|
||||
Body = "A new unassigned issue",
|
||||
};
|
||||
newIssue.Labels.Add("something");
|
||||
|
||||
var issue = await _issuesClient.Create(owner, _repository.Name, newIssue);
|
||||
|
||||
var issueUpdate = issue.ToUpdate();
|
||||
|
||||
var updatedIssue = await _issuesClient.Update(owner, _repository.Name, issue.Number, issueUpdate);
|
||||
|
||||
Assert.Equal(1, updatedIssue.Labels.Count);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanUpdateLabelForAnIssue()
|
||||
{
|
||||
var owner = _repository.Owner.Login;
|
||||
|
||||
// create some labels
|
||||
await _issuesClient.Labels.Create(owner, _repository.Name, new NewLabel("something", "FF0000"));
|
||||
await _issuesClient.Labels.Create(owner, _repository.Name, new NewLabel("another thing", "0000FF"));
|
||||
|
||||
// setup us the issue
|
||||
var newIssue = new NewIssue("A test issue1")
|
||||
{
|
||||
Body = "A new unassigned issue",
|
||||
};
|
||||
newIssue.Labels.Add("something");
|
||||
|
||||
var issue = await _issuesClient.Create(owner, _repository.Name, newIssue);
|
||||
|
||||
// update the issue
|
||||
var issueUpdate = issue.ToUpdate();
|
||||
issueUpdate.AddLabel("another thing");
|
||||
|
||||
var updatedIssue = await _issuesClient.Update(owner, _repository.Name, issue.Number, issueUpdate);
|
||||
|
||||
Assert.Equal("another thing", updatedIssue.Labels[0].Name);
|
||||
}
|
||||
|
||||
[IntegrationTest]
|
||||
public async Task CanClearLabelsForAnIssue()
|
||||
{
|
||||
var owner = _repository.Owner.Login;
|
||||
|
||||
// create some labels
|
||||
await _issuesClient.Labels.Create(owner, _repository.Name, new NewLabel("something", "FF0000"));
|
||||
await _issuesClient.Labels.Create(owner, _repository.Name, new NewLabel("another thing", "0000FF"));
|
||||
|
||||
// setup us the issue
|
||||
var newIssue = new NewIssue("A test issue1")
|
||||
{
|
||||
Body = "A new unassigned issue",
|
||||
};
|
||||
newIssue.Labels.Add("something");
|
||||
newIssue.Labels.Add("another thing");
|
||||
|
||||
var issue = await _issuesClient.Create(owner, _repository.Name, newIssue);
|
||||
Assert.Equal(2, issue.Labels.Count);
|
||||
|
||||
// update the issue
|
||||
var issueUpdate = issue.ToUpdate();
|
||||
issueUpdate.ClearLabels();
|
||||
|
||||
var updatedIssue = await _issuesClient.Update(owner, _repository.Name, issue.Number, issueUpdate);
|
||||
|
||||
Assert.Empty(updatedIssue.Labels);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Helper.DeleteRepo(_repository);
|
||||
|
||||
@@ -257,11 +257,9 @@ public class IssueTest
|
||||
|
||||
var update = issue.ToUpdate();
|
||||
|
||||
Assert.Equal("bug", update.Labels.Single());
|
||||
Assert.Null(update.Labels);
|
||||
Assert.Equal(1, update.Milestone.GetValueOrDefault());
|
||||
Assert.Equal("octocat", update.Assignee);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -9,13 +9,8 @@ namespace Octokit
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class IssueUpdate
|
||||
{
|
||||
public IssueUpdate()
|
||||
{
|
||||
Labels = new List<string>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Title of the milestone (required)
|
||||
/// Title of the issue (required)
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
@@ -66,7 +61,26 @@ namespace Octokit
|
||||
|
||||
public void AddLabel(string name)
|
||||
{
|
||||
// lazily create the label array
|
||||
if (Labels == null)
|
||||
{
|
||||
Labels = new List<string>();
|
||||
}
|
||||
|
||||
Labels.Add(name);
|
||||
}
|
||||
|
||||
public void ClearLabels()
|
||||
{
|
||||
// lazily create the label array
|
||||
if (Labels == null)
|
||||
{
|
||||
Labels = new List<string>();
|
||||
}
|
||||
else
|
||||
{
|
||||
Labels.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,6 @@ namespace Octokit
|
||||
/// <summary>
|
||||
/// The user that created the issue
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Specify "none" for issues with no assigned user
|
||||
/// </remarks>
|
||||
public string Creator { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -127,11 +127,6 @@ namespace Octokit
|
||||
Title = Title
|
||||
};
|
||||
|
||||
foreach (var label in Labels.Select(l => l.Name))
|
||||
{
|
||||
issueUpdate.Labels.Add(label);
|
||||
}
|
||||
|
||||
return issueUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
# Working with Issues
|
||||
|
||||
There's three typical operations you have available when working
|
||||
with issues - viewing, creating or editing issues.
|
||||
|
||||
### Get All
|
||||
|
||||
If you want to view all assigned, open issues against repositories you belong to
|
||||
(either you own them, or you belong to a team or organization), use this
|
||||
method:
|
||||
|
||||
```
|
||||
var issues = await client.Issue.GetAllForCurrent();
|
||||
```
|
||||
|
||||
If you want to skip organization repositories, you can instead use this
|
||||
rather verbose method:
|
||||
|
||||
```
|
||||
var issues = await client.Issue.GetAllForOwnedAndMemberRepositories();
|
||||
```
|
||||
|
||||
If you know the specific repository, just invoke that:
|
||||
|
||||
```
|
||||
var issuesForOctokit = await client.Issue.GetForRepository("octokit", "octokit.net");
|
||||
```
|
||||
|
||||
### Filtering
|
||||
|
||||
Each of these methods has an overload which takes a parameter to filter results.
|
||||
|
||||
The simplest request is `IssueRequest` which has these options:
|
||||
|
||||
- `Filter` - specify which issues to display - by default it will display issues assigned to you
|
||||
- `State` - by default it will display open issues, you can specify closed or all issues
|
||||
- `Labels` - specify a set of labels to include
|
||||
- `SortProperty` - sort by when the issue was created, when it was updated, or comment count
|
||||
- `SortDirection` - whether to sort in ascending or descending fashion
|
||||
- `Since` - ignore issues before a specific date
|
||||
|
||||
For example, this is how you could find all issues updated in the past two weeks:
|
||||
|
||||
```
|
||||
var recently = new IssueRequest
|
||||
{
|
||||
Filter = IssueFilter.All,
|
||||
State = ItemState.All,
|
||||
Since = DateTimeOffset.Now.Subtract(TimeSpan.FromDays(14))
|
||||
};
|
||||
var issues = await client.Issue.GetAllForCurrent(recently);
|
||||
```
|
||||
|
||||
`RepositoryIssueRequest` extends `IssueRequest` and adds these options:
|
||||
|
||||
- `Milestone` - use `*` for any issue in a milestone, "none" for issues not assigned to a milestone
|
||||
- `Assignee` - specify the GitHub username, or "none" for unassigned issues
|
||||
- `Creator` - specify the GitHub username
|
||||
- `Mentioned` - specify the GitHub username
|
||||
|
||||
For example, to find all issues which need to be prioritized:
|
||||
|
||||
```
|
||||
var shouldPrioritize = new RepositoryIssueRequest
|
||||
{
|
||||
Assignee = "none",
|
||||
Milestone = "none",
|
||||
Filter = IssueFilter.All
|
||||
};
|
||||
var issues = await client.Issue.GetForRepository("octokit", "octokit.net", shouldPrioritize);
|
||||
```
|
||||
|
||||
### Create
|
||||
|
||||
At a minimum, you need to specify the title:
|
||||
|
||||
```
|
||||
var createIssue = new NewIssue("this thing doesn't work");
|
||||
var issue = await _issuesClient.Create("octokit", "octokit.net", createIssue);
|
||||
```
|
||||
|
||||
`Create` returns a `Task<Issue>` which represents the created issue.
|
||||
|
||||
There's also a number of additional fields:
|
||||
|
||||
- `Body` - details about the issue (Markdown)
|
||||
- `Assignee` - the GitHub user to associate with the issue
|
||||
- `Milestone` - the milestone id to assign the issue to
|
||||
- `Labels` - a collection of labels to assign to the issue
|
||||
|
||||
Note that `Milestones` and `Labels` need to exist in the repository before
|
||||
creating the issue. Refer to the [Milestones](https://github.com/octokit/octokit.net/blob/master/docs/milestones.md)
|
||||
and [Labels](https://github.com/octokit/octokit.net/blob/master/docs/labels.md)
|
||||
sections for more details.
|
||||
|
||||
### Update
|
||||
|
||||
You can either hold the new issue in memory, or use the id to fetch the issue
|
||||
later:
|
||||
|
||||
```
|
||||
var issue = await client.Issue.Get("octokit", "octokit.net", 405);
|
||||
```
|
||||
|
||||
With this issue, you can transform it into an `IssueUpdate` using the extension method:
|
||||
|
||||
```
|
||||
var update = issue.ToUpdate();
|
||||
```
|
||||
|
||||
This creates an `IssueUpdate` which lets you specify the neccessary changes.
|
||||
Label changes probably requires some explanation:
|
||||
|
||||
- by default, no labels are set in an `IssueUpdate` - this is to indicate
|
||||
to the server that no change is necessary when doing the update
|
||||
- to set a new label as part of the update, call `AddLabel()` specifying
|
||||
the name of the new label
|
||||
- to remove all labels as part of the update, call `ClearLabels()`
|
||||
|
||||
If you're trying to populate the `Labels` collection by hand, you might hit
|
||||
some exceptional behaviour due to these rules.
|
||||
@@ -0,0 +1 @@
|
||||
# Working with Issue Labels
|
||||
@@ -0,0 +1 @@
|
||||
# Working with Milestones
|
||||
Reference in New Issue
Block a user