зеркало из https://github.com/mislav/hub.git
Automatically retry creating a PR after 422 on `--push`
Since `--push` has just created a new branch, there could be a slight delay before GitHub registers it, and there's a possibility that a 422 would be returned for the "head" field. If that happens, retry the POST a couple of times until it either succeeds or times out.
This commit is contained in:
Родитель
d68e6e4a78
Коммит
2437c48e65
|
@ -5,6 +5,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/github/hub/git"
|
"github.com/github/hub/git"
|
||||||
"github.com/github/hub/github"
|
"github.com/github/hub/github"
|
||||||
|
@ -264,7 +265,35 @@ func pullRequest(cmd *Command, args *Args) {
|
||||||
issueNum, _ := strconv.Atoi(flagPullRequestIssue)
|
issueNum, _ := strconv.Atoi(flagPullRequestIssue)
|
||||||
params["issue"] = issueNum
|
params["issue"] = issueNum
|
||||||
}
|
}
|
||||||
pr, err := client.CreatePullRequest(baseProject, params)
|
|
||||||
|
startedAt := time.Now()
|
||||||
|
numRetries := 0
|
||||||
|
retryDelay := 2
|
||||||
|
retryAllowance := 0
|
||||||
|
if flagPullRequestPush {
|
||||||
|
retryAllowance = 9
|
||||||
|
}
|
||||||
|
|
||||||
|
var pr *github.PullRequest
|
||||||
|
for {
|
||||||
|
pr, err = client.CreatePullRequest(baseProject, params)
|
||||||
|
if err != nil && strings.Contains(err.Error(), `Invalid value for "head"`) {
|
||||||
|
if retryAllowance > 0 {
|
||||||
|
retryAllowance -= retryDelay
|
||||||
|
time.Sleep(time.Duration(retryDelay) * time.Second)
|
||||||
|
retryDelay += 1
|
||||||
|
numRetries += 1
|
||||||
|
} else {
|
||||||
|
if numRetries > 0 {
|
||||||
|
duration := time.Now().Sub(startedAt)
|
||||||
|
err = fmt.Errorf("%s\nGiven up after retrying for %.1f seconds.", err, duration.Seconds())
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if err == nil && editor != nil {
|
if err == nil && editor != nil {
|
||||||
defer editor.DeleteFile()
|
defer editor.DeleteFile()
|
||||||
|
|
|
@ -500,17 +500,29 @@ BODY
|
||||||
Given I am on the "feature" branch with upstream "origin/feature"
|
Given I am on the "feature" branch with upstream "origin/feature"
|
||||||
Given the GitHub API server:
|
Given the GitHub API server:
|
||||||
"""
|
"""
|
||||||
|
tries = 0
|
||||||
post('/repos/mislav/coral/pulls') {
|
post('/repos/mislav/coral/pulls') {
|
||||||
status 422
|
tries += 1
|
||||||
json(:message => "I haz fail!")
|
if tries == 1
|
||||||
|
status 422
|
||||||
|
json :message => 'Validation Failed',
|
||||||
|
:errors => [{
|
||||||
|
:resource => 'PullRequest',
|
||||||
|
:code => 'invalid',
|
||||||
|
:field => 'head'
|
||||||
|
}]
|
||||||
|
else
|
||||||
|
status 400
|
||||||
|
end
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
When I run `hub pull-request -m message`
|
When I run `hub pull-request -m message`
|
||||||
Then the stderr should contain exactly:
|
Then the stderr should contain exactly:
|
||||||
"""
|
"""
|
||||||
Error creating pull request: Unprocessable Entity (HTTP 422)
|
Error creating pull request: Unprocessable Entity (HTTP 422)
|
||||||
I haz fail!\n
|
Invalid value for "head"\n
|
||||||
"""
|
"""
|
||||||
|
And the exit status should be 1
|
||||||
|
|
||||||
Scenario: Convert issue to pull request
|
Scenario: Convert issue to pull request
|
||||||
Given I am on the "feature" branch with upstream "origin/feature"
|
Given I am on the "feature" branch with upstream "origin/feature"
|
||||||
|
@ -842,3 +854,66 @@ BODY
|
||||||
And the exit status should be 1
|
And the exit status should be 1
|
||||||
And the file ".git/PULLREQ_EDITMSG" should not exist
|
And the file ".git/PULLREQ_EDITMSG" should not exist
|
||||||
And "git push origin HEAD:topic" should not be run
|
And "git push origin HEAD:topic" should not be run
|
||||||
|
|
||||||
|
Scenario: Automatically retry when --push resulted in 422
|
||||||
|
Given The default aruba timeout is 7 seconds
|
||||||
|
And the text editor adds:
|
||||||
|
"""
|
||||||
|
hello!
|
||||||
|
"""
|
||||||
|
Given the GitHub API server:
|
||||||
|
"""
|
||||||
|
first_try_at = nil
|
||||||
|
tries = 0
|
||||||
|
|
||||||
|
post('/repos/mislav/coral/pulls') {
|
||||||
|
tries += 1
|
||||||
|
assert :title => 'hello!', :head => 'mislav:topic'
|
||||||
|
|
||||||
|
if !first_try_at || (Time.now - first_try_at) < 5
|
||||||
|
first_try_at ||= Time.now
|
||||||
|
status 422
|
||||||
|
json :message => 'Validation Failed',
|
||||||
|
:errors => [{
|
||||||
|
:resource => 'PullRequest',
|
||||||
|
:code => 'invalid',
|
||||||
|
:field => 'head'
|
||||||
|
}]
|
||||||
|
else
|
||||||
|
status 201
|
||||||
|
json :html_url => "the://url?tries=#{tries}"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
Given I am on the "topic" branch
|
||||||
|
When I successfully run `hub pull-request -p`
|
||||||
|
Then the output should contain exactly "the://url?tries=3\n"
|
||||||
|
And the file ".git/PULLREQ_EDITMSG" should not exist
|
||||||
|
|
||||||
|
Scenario: Eventually give up on retries for --push
|
||||||
|
Given The default aruba timeout is 12 seconds
|
||||||
|
And the text editor adds:
|
||||||
|
"""
|
||||||
|
hello!
|
||||||
|
"""
|
||||||
|
Given the GitHub API server:
|
||||||
|
"""
|
||||||
|
post('/repos/mislav/coral/pulls') {
|
||||||
|
status 422
|
||||||
|
json :message => 'Validation Failed',
|
||||||
|
:errors => [{
|
||||||
|
:resource => 'PullRequest',
|
||||||
|
:code => 'invalid',
|
||||||
|
:field => 'head'
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
Given I am on the "topic" branch
|
||||||
|
When I run `hub pull-request -p`
|
||||||
|
Then the stderr should contain:
|
||||||
|
"""
|
||||||
|
Error creating pull request: Unprocessable Entity (HTTP 422)
|
||||||
|
Invalid value for "head"\n
|
||||||
|
"""
|
||||||
|
And the output should match /Given up after retrying for 9\.\d seconds\./
|
||||||
|
And a file named ".git/PULLREQ_EDITMSG" should exist
|
||||||
|
|
Загрузка…
Ссылка в новой задаче