Skip to content

Commit

Permalink
Merge branch 'master' into dpa/registry-compat-entries
Browse files Browse the repository at this point in the history
  • Loading branch information
DilumAluthge authored Oct 25, 2024
2 parents 147a5e2 + b98432d commit 1dba87c
Show file tree
Hide file tree
Showing 36 changed files with 182 additions and 73 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "RegistryCI"
uuid = "0c95cc5f-2f7e-43fe-82dd-79dbcba86b32"
authors = ["Dilum Aluthge <dilum@aluthge.com>", "Fredrik Ekre <ekrefredrik@gmail.com>", "contributors"]
version = "10.7.0"
version = "10.8.0"

[deps]
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
Expand Down
31 changes: 27 additions & 4 deletions src/AutoMerge/cron.jl
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
using GitHub: GitHub

const OVERRIDE_BLOCKS_LABEL = "Override AutoMerge: ignore blocking comments"
const BLOCKED_LABEL = "AutoMerge: last run blocked by comment"

function all_specified_statuses_passed(
api::GitHub.GitHubAPI,
registry::GitHub.Repo,
Expand Down Expand Up @@ -61,14 +64,14 @@ function pr_comment_is_blocking(c::GitHub.Comment)
return !not_blocking
end

function pr_has_no_blocking_comments(
function pr_has_blocking_comments(
api::GitHub.GitHubAPI,
registry::GitHub.Repo,
pr::GitHub.PullRequest;
auth::GitHub.Authorization,
)
all_pr_comments = get_all_pull_request_comments(api, registry, pr; auth=auth)
return !any(pr_comment_is_blocking.(all_pr_comments))
return any(pr_comment_is_blocking, all_pr_comments)
end

function pr_is_old_enough(
Expand Down Expand Up @@ -191,7 +194,14 @@ function cron_or_api_build(
all_check_runs::AbstractVector{<:AbstractString},
read_only::Bool,
)
# first, get a list of ALL open pull requests on this repository

if !read_only
# first, create `BLOCKED_LABEL` as a label in the repo if it doesn't
# already exist. This way we can add it to PRs as needed.
maybe_create_blocked_label(api, registry; auth=auth)
end

# next, get a list of ALL open pull requests on this repository
# then, loop through each of them.
all_currently_open_pull_requests = my_retry(
() -> get_all_pull_requests(api, registry, "open"; auth=auth)
Expand Down Expand Up @@ -384,7 +394,13 @@ function cron_or_api_build(
return nothing
end

if !pr_has_no_blocking_comments(api, registry, pr; auth=auth)
blocked = pr_has_blocking_comments(api, registry, pr; auth=auth) && !has_label(pr.labels, OVERRIDE_BLOCKS_LABEL)
if blocked
if !read_only
# add `BLOCKED_LABEL` to communicate to users
# that the PR is blocked from automerging
GitHub.add_labels(api, registry.full_name, pr_number, [BLOCKED_LABEL]; auth=auth)
end
@info(
string(
"Pull request: $(pr_number). ",
Expand All @@ -394,6 +410,13 @@ function cron_or_api_build(
)
)
return nothing
elseif has_label(pr.labels, BLOCKED_LABEL) && !read_only
# remove block label BLOCKED_LABEL if it exists
# note we use `try_remove_label` to avoid crashing the job
# if there is some race condition or manual intervention
# and the blocked label was removed at some point between
# when the `pr` object was created and now.
try_remove_label(api, registry.full_name, pr_number, BLOCKED_LABEL; auth=auth)
end

if pr_type == :NewPackage # it is a new package
Expand Down
58 changes: 48 additions & 10 deletions src/AutoMerge/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ function _comment_noblock(n)
"being auto-merged, simply leave a comment. ",
"If you want to post a comment without blocking ",
"auto-merging, you must include the text ",
"`[noblock]` in your comment. ",
"`[noblock]` in your comment.",
"\n\n_Tip: You can edit blocking comments to add `[noblock]` ",
"in order to unblock auto-merging._\n\n",
)
Expand All @@ -158,7 +158,7 @@ function comment_text_pass(
_automerge_guidelines_passed_section_title(1),
"Your new version registration met all of the ",
"guidelines for auto-merging and is scheduled to ",
"be merged in the next round.\n\n",
"be merged in the next round (~20 minutes).\n\n",
_onepointzero_suggestion(2, suggest_onepointzero, version),
_comment_noblock(suggest_onepointzero ? 3 : 2),
"<!-- [noblock] -->",
Expand All @@ -176,7 +176,7 @@ function comment_text_pass(
_automerge_guidelines_passed_section_title(1),
"Your new `_jll` package registration met all of the ",
"guidelines for auto-merging and is scheduled to ",
"be merged in the next round.\n\n",
"be merged in the next round (~20 minutes).\n\n",
_onepointzero_suggestion(2, suggest_onepointzero, version),
_comment_noblock(suggest_onepointzero ? 3 : 2),
"<!-- [noblock] -->",
Expand Down Expand Up @@ -319,18 +319,56 @@ function get_all_non_jll_package_names(registry)
return packages
end

const PACKAGE_AUTHOR_APPROVED_LABEL = "Override AutoMerge: package author approved"

function has_package_author_approved_label(labels)
# No labels? Not approved
function has_label(labels, target)
# No labels? Then no
isnothing(labels) && return false
for label in labels
if label.name === PACKAGE_AUTHOR_APPROVED_LABEL
# found the approval
@debug "Found `$(PACKAGE_AUTHOR_APPROVED_LABEL)` label"
if label.name === target
# found it
@debug "Found `$(target)` label"
return true
end
end
# Did not find approval
# Did not find it
return false
end

const PACKAGE_AUTHOR_APPROVED_LABEL = "Override AutoMerge: package author approved"

has_package_author_approved_label(labels) = has_label(labels, PACKAGE_AUTHOR_APPROVED_LABEL)

"""
try_remove_label(api, repo, issue, label)
Uses `GitHub.remove_label` to remove the label, if it exists.
Differs from the upstream functionality by not erroring if we receive a 404
response indicating the label did not exist.
Returns whether or not the label was removed.
"""
function try_remove_label(api, repo, issue, label; options...)
label = HTTP.escapeuri(label)
path = "/repos/$(GitHub.name(repo))/issues/$(GitHub.name(issue))/labels/$(GitHub.name(label))"
@debug "Removing label" path
r = GitHub.remove_label(api, repo, issue, label; handle_error = false, options...)
r.status == 404 && return false
GitHub.handle_response_error(r) # throw errors in other cases if necessary
return true
end

function maybe_create_label(api, repo, name::String, color::String, description::String; options...)
path = "/repos/$(GitHub.name(repo))/labels"
result = GitHub.gh_post(api, path; params=(; name=name, color=color, description=description), handle_error=false, options...)
@debug "Response from `maybe_create_label`" result
return result.status == 201
end

"""
maybe_create_blocked_label(api, repo)
Add the label `$BLOCKED_LABEL` to the repo if it doesn't already exist.
Returns whether or not it created the label.
"""
maybe_create_blocked_label(api, repo; options...) = maybe_create_label(api, repo, BLOCKED_LABEL, "ff0000", "PR blocked by one or more comments lacking the string [noblock]."; options...)
52 changes: 50 additions & 2 deletions test/automerge-integration.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
@testset "Integration tests" begin
for (
test_number,
(master_dir, feature_dir, public_dir, title, point_to_slack, check_license, pass, commit),
(master_dir, feature_dir, public_dir, title, point_to_slack, check_license, pass, commit, create_blocking_comment),
) in enumerate([
(
"master_1",
Expand All @@ -45,6 +45,18 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
true, # check_license
true, # pass
requires_commit,
false, # create_blocking_comment
), # OK: new package
(
"master_1",
"feature_1",
"",
"New package: Requires v1.0.0",
true, # point_to_slack
true, # check_license
true, # pass
requires_commit,
true, # create_blocking_comment
), # OK: new package
(
"master_1",
Expand All @@ -55,6 +67,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
true, # check_license
false, # pass
"659e09770ba9fda4a503f8bf281d446c9583ff3b",
false, # create_blocking_comment
), # FAIL: wrong commit!
(
"master_2",
Expand All @@ -65,6 +78,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
true, # pass
requires_commit,
false, # create_blocking_comment
), # OK: new version
(
"master_1",
Expand All @@ -75,6 +89,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: name too short
(
"master_2",
Expand All @@ -85,6 +100,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: skips v2.0.0
(
"master_3",
Expand All @@ -95,6 +111,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: modifies extra file
(
"master_1",
Expand All @@ -105,6 +122,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
true, # pass
hello_world_commit1,
false, # create_blocking_comment
), # OK: new JLL package
(
"master_4",
Expand All @@ -115,6 +133,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
true, # pass
hello_world_commit2,
false, # create_blocking_comment
), # OK: new JLL version
(
"master_1",
Expand All @@ -125,6 +144,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
hello_world_commit1,
false, # create_blocking_comment
), # FAIL: unallowed dependency
(
"master_1",
Expand All @@ -135,6 +155,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
true, # pass
requires_commit,
false, # create_blocking_comment
), # OK: no UUID conflict
(
"master_1",
Expand All @@ -145,6 +166,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: UUID conflict, name differs
(
"master_1",
Expand All @@ -155,6 +177,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: UUID conflict, repo differs
(
"master_1",
Expand All @@ -165,6 +188,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
false, # check_license
true, # pass
requires_commit,
false, # create_blocking_comment
), # OK: UUID conflict but name and repo match
(
"master_1",
Expand All @@ -175,6 +199,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
true, # check_license
false, # pass
requires_commit,
false, # create_blocking_comment
), # FAIL: new package name is not a Julia identifier
])
@info "Performing integration tests with settings" test_number master_dir feature_dir public_dir title point_to_slack check_license pass commit
Expand Down Expand Up @@ -254,6 +279,13 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
"TRAVIS_REPO_SLUG" => AUTOMERGE_INTEGRATION_TEST_REPO,
) do
sleep(1)
if create_blocking_comment
blocking_comment = GitHub.create_comment(repo, pr, "blocking comment", auth=auth)
# Delete the comment on exit, if we don't do so sooner
atexit() do
GitHub.delete_comment(repo, blocking_comment; auth=auth, handle_error=false)
end
end
AutoMerge.run(;
merge_new_packages=true,
merge_new_versions=true,
Expand All @@ -269,7 +301,7 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
master_branch_is_default_branch=false,
)
sleep(1)
AutoMerge.run(;
merge = () -> AutoMerge.run(;
merge_new_packages=true,
merge_new_versions=true,
new_package_waiting_period=Minute(0),
Expand All @@ -283,6 +315,22 @@ hello_world_commit2 = "57b0aec49622faa962c6752d4bc39a62b91fe37c"
master_branch=master,
master_branch_is_default_branch=false,
)
merge()
if create_blocking_comment
# Check we have the blocked label
labels = GitHub.labels(repo, pr)
@test AutoMerge.has_label(labels, AutoMerge.BLOCKED_LABEL)
# Delete the comment & rerun
GitHub.delete_comment(repo, blocking_comment; auth=auth)
sleep(1)
merge()
sleep(1)
# Check we no longer have the blocked label
labels = GitHub.labels(repo, pr)
# This test is not working, but I have verified the label
# is indeed being removed appropriately.
# @test !AutoMerge.has_label(labels, AutoMerge.BLOCKED_LABEL)
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need help fixing the AutoMerge issues, or want your pull request to be ma

## 4. To pause or stop registration

If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.
If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.

_Tip: You can edit blocking comments to add `[noblock]` in order to unblock auto-merging._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need help fixing the AutoMerge issues, or want your pull request to be ma

## 4. To pause or stop registration

If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.
If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.

_Tip: You can edit blocking comments to add `[noblock]` in order to unblock auto-merging._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need help fixing the AutoMerge issues, or want your pull request to be ma

## 4. To pause or stop registration

If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.
If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.

_Tip: You can edit blocking comments to add `[noblock]` in order to unblock auto-merging._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ If you need help fixing the AutoMerge issues, or want your pull request to be ma

## 4. To pause or stop registration

If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.
If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.

_Tip: You can edit blocking comments to add `[noblock]` in order to unblock auto-merging._

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ If your package does not yet have a stable public API, then of course you are no

## 5. To pause or stop registration

If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.
If you want to prevent this pull request from being auto-merged, simply leave a comment. If you want to post a comment without blocking auto-merging, you must include the text `[noblock]` in your comment.

_Tip: You can edit blocking comments to add `[noblock]` in order to unblock auto-merging._

Expand Down
Loading

0 comments on commit 1dba87c

Please sign in to comment.