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:
Mislav Marohnić 2016-10-22 12:10:00 +02:00
Родитель d68e6e4a78
Коммит 2437c48e65
2 изменённых файлов: 108 добавлений и 4 удалений

Просмотреть файл

@ -5,6 +5,7 @@ import (
"regexp"
"strconv"
"strings"
"time"
"github.com/github/hub/git"
"github.com/github/hub/github"
@ -264,7 +265,35 @@ func pullRequest(cmd *Command, args *Args) {
issueNum, _ := strconv.Atoi(flagPullRequestIssue)
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 {
defer editor.DeleteFile()

Просмотреть файл

@ -500,17 +500,29 @@ BODY
Given I am on the "feature" branch with upstream "origin/feature"
Given the GitHub API server:
"""
tries = 0
post('/repos/mislav/coral/pulls') {
status 422
json(:message => "I haz fail!")
tries += 1
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`
Then the stderr should contain exactly:
"""
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
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 file ".git/PULLREQ_EDITMSG" should not exist
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