Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add subdirectory registration functionality #287

Merged
merged 11 commits into from
Apr 27, 2020
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ JSON = "0.20, 0.21"
MbedTLS = "0.6.8, 0.7, 1"
Mustache = "0.5, 1.0"
Mux = "0.7"
RegistryTools = "1.3.1"
RegistryTools = "1.5.0"
TimeToLive = "0.2, 0.3"
ZMQ = "1"
julia = "1.1"
Expand Down
15 changes: 11 additions & 4 deletions src/commentbot/CommentBot.jl
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,16 @@ get_trigger_id(rp::RequestParams{PullRequestTrigger}) = rp.trigger_src.prid
get_trigger_id(rp::RequestParams{IssueTrigger}) = get_prid(rp.evt.payload)
get_trigger_id(rp::RequestParams{CommitCommentTrigger}) = get_comment_commit_id(rp.evt)

tag_name(version, subdir) = subdir == "" ? "v$version" : splitdir(subdir)[end] * "-v$version"

function make_pull_request(pp::ProcessedParams, rp::RequestParams, rbrn::RegBranch, target_registry::Dict{String,Any})
name = rbrn.name
ver = rbrn.version
brn = rbrn.branch
subdir = rp.subdir

@info("Creating pull request name=$name, ver=$ver, branch=$brn")
subdir_string = subdir == "" ? "" : ", subdir=$subdir"
@info("Creating pull request name=$name, ver=$ver, branch=$brn" * subdir_string)
payload = rp.evt.payload
creator = get_user_login(payload)
reviewer = payload["sender"]["login"]
Expand All @@ -62,7 +66,8 @@ function make_pull_request(pp::ProcessedParams, rp::RequestParams, rbrn::RegBran
"pkg_repo_name"=> rp.reponame,
"trigger_id"=> trigger_id,
"tree_sha"=> pp.tree_sha,
"version"=> string(ver)))
"version"=> string(ver),
"subdir"=> subdir))
key = CONFIG["enc_key"]
enc_meta = "<!-- " * bytes2hex(encrypt(MbedTLS.CIPHER_AES_128_CBC, key, meta, key)) * " -->"
params = Dict("base"=>target_registry["base_branch"],
Expand All @@ -85,6 +90,7 @@ function make_pull_request(pp::ProcessedParams, rp::RequestParams, rbrn::RegBran

repo = join(split(target_registry["repo"], "/")[end-1:end], "/")
pr, msg = create_or_find_pull_request(repo, params, rbrn)
tag = tag_name(ver, subdir)

cbody = """
Registration pull request $msg: [$(repo)/$(pr.number)]($(pr.html_url))
Expand All @@ -93,8 +99,8 @@ function make_pull_request(pp::ProcessedParams, rp::RequestParams, rbrn::RegBran

This will be done automatically if the [Julia TagBot GitHub Action](https://github.com/marketplace/actions/julia-tagbot) is installed, or can be done manually through the github interface, or via:
```
git tag -a v$(string(ver)) -m "<description of version>" $(pp.sha)
git push origin v$(string(ver))
git tag -a $tag -m "<description of version>" $(pp.sha)
git push origin $tag
```
"""

Expand Down Expand Up @@ -138,6 +144,7 @@ function action(rp::RequestParams{T}, zsock::RequestSocket) where T <: RegisterT
regp = RegisterParams(pp.cloneurl,
pp.project,
pp.tree_sha;
subdir=rp.subdir,
registry=target_registry["repo"],
registry_deps=registry_deps,
push=true,
Expand Down
18 changes: 10 additions & 8 deletions src/commentbot/approval.jl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
function tag_package(rname, ver::VersionNumber, mcs, auth)
function tag_package(rname, ver::VersionNumber, mcs, auth; tag_name = "v$ver")
tagger = Dict("name" => CONFIG["github"]["user"],
"email" => CONFIG["github"]["email"],
"date" => Dates.format(now(), dateformat"YYYY-mm-ddTHH:MM:SSZ"))
create_tag(rname; auth=auth,
params=Dict("tag" => "v$ver",
"message" => "Release: v$ver",
params=Dict("tag" => tag_name,
"message" => "Release: $tag_name",
"object" => mcs,
"type" => "commit",
"tagger" => tagger))
Expand Down Expand Up @@ -46,6 +46,7 @@ function handle_approval(rp::RequestParams{ApprovalTrigger})
tree_sha = d["tree_sha"]
trigger_id = d["trigger_id"]
request_type = d["request_type"]
subdir = d["subdir"]

if request_type == "pull_request"
pr = pull_request(reponame, trigger_id; auth=auth)
Expand All @@ -60,13 +61,14 @@ function handle_approval(rp::RequestParams{ApprovalTrigger})
end

tag_exists = false
tag = tag_name(ver, subdir)
# Get tags in a try-catch block as GitHub.jl error if no tag exists
try
ts = tags(reponame; auth=auth, page_limit=1, params=Dict("per_page" => 15))[1]
for t in ts
if split(t.url.path, "/")[end] == "v$ver"
if split(t.url.path, "/")[end] == tag
if t.object["sha"] != tree_sha
return "Tag with name `v$ver` already exists and points to a different commit"
return "Tag with name `$tag` already exists and points to a different commit"
end
tag_exists = true
@debug("Tag already exists", reponame, ver, tree_sha)
Expand All @@ -83,15 +85,15 @@ function handle_approval(rp::RequestParams{ApprovalTrigger})

if !tag_exists
@debug("Creating new tag", reponame, ver, tree_sha)
tag_package(reponame, ver, tree_sha, auth)
tag_package(reponame, ver, tree_sha, auth; tag_name = tag)
end

release_exists = false
if tag_exists
# Look for release in last 15 releases
rs = releases(reponame; auth=auth, page_limit=1, params=Dict("per_page"=>15))[1]
for r in rs
if r.name == "v$ver"
if r.name == tag
release_exists = true
@debug("Release already exists", r.name)
break
Expand All @@ -102,7 +104,7 @@ function handle_approval(rp::RequestParams{ApprovalTrigger})
if !release_exists
@debug("Creating new release", ver)
create_release(reponame; auth=auth,
params=Dict("tag_name" => "v$ver", "name" => "v$ver"))
params=Dict("tag_name" => tag, "name" => tag))
end

if request_type == "issue"
Expand Down
22 changes: 11 additions & 11 deletions src/commentbot/param_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ struct RequestParams{T<:RequestTrigger}
trigger_src::T
commenter_can_register::Bool
target::Union{Nothing,String}
subdir::String
cparams::CommonParams

function RequestParams(evt::WebhookEvent, phrase::RegexMatch)
Expand All @@ -34,6 +35,7 @@ struct RequestParams{T<:RequestTrigger}
end

branch = get(action_kwargs, :branch, "master")
subdir = get(action_kwargs, :subdir, "")
target = get(action_kwargs, :target, nothing)

if evt.payload["repository"]["private"] && get(CONFIG, "disable_private_registrations", true)
Expand Down Expand Up @@ -100,7 +102,7 @@ struct RequestParams{T<:RequestTrigger}
@debug("Event pre-check validity: $isvalid")

return new{typeof(trigger_src)}(evt, phrase, reponame, notes, trigger_src,
commenter_can_register, target,
commenter_can_register, target, subdir,
CommonParams(isvalid, err, report_error))
end
end
Expand Down Expand Up @@ -131,7 +133,8 @@ function istagwrong(
rp::RequestParams,
commit_sha::String,
ver::VersionNumber,
auth,
auth;
tag = "v$ver"
)
# Look for tag in last 15 tags
ts = try
Expand All @@ -140,13 +143,9 @@ function istagwrong(
catch ex
[]
end
ver = string(ver)
for t in ts
tag_name = split(t.url.path, "/")[end]
if startswith(tag_name, "v")
tag_name = tag_name[2:end]
end
if tag_name == ver
name = split(t.url.path, "/")[end]
if name == tag
if t.object["sha"] != commit_sha
return true
end
Expand Down Expand Up @@ -190,7 +189,7 @@ struct ProcessedParams
cloneurl, sha, err = get_cloneurl_and_sha(rp, auth)

if err === nothing && sha !== nothing
project, tree_sha, projectfile_found, projectfile_valid, err = verify_projectfile_from_sha(rp.reponame, sha; auth = auth)
project, tree_sha, projectfile_found, projectfile_valid, err = verify_projectfile_from_sha(rp.reponame, sha; auth = auth, subdir = rp.subdir)
if !projectfile_found
err = "File (Julia)Project.toml not found"
@debug(err)
Expand All @@ -199,9 +198,10 @@ struct ProcessedParams

wrongtag = false
if err === nothing
wrongtag = istagwrong(rp, sha, project.version, auth)
tag = tag_name(project.version, rp.subdir)
wrongtag = istagwrong(rp, sha, project.version, auth, tag = tag)
if wrongtag
err = "Tag with name `$(project.version)` already exists and points to a different commit"
err = "Tag with name `$tag` already exists and points to a different commit"
@debug(err, rp.reponame, project.version)
end
end
Expand Down
16 changes: 10 additions & 6 deletions src/commentbot/verify_projectfile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,22 @@ function pfile_hasfields(p::Pkg.Types.Project)
return true, nothing
end

function verify_projectfile_from_sha(reponame, sha; auth=GitHub.AnonymousAuth())
function verify_projectfile_from_sha(reponame, commit_sha; auth=GitHub.AnonymousAuth(), subdir = "")
project = nothing
projectfile_found = false
projectfile_valid = false
err = nothing
@debug("Getting gitcommit object for sha")
gcom = gitcommit(reponame, GitCommit(Dict("sha"=>sha)); auth=auth)
gcom = gitcommit(reponame, GitCommit(Dict("sha"=>commit_sha)); auth=auth)
@debug("Getting tree object for sha")
t = tree(reponame, Tree(gcom.tree); auth=auth)
t = tree(reponame, Tree(gcom.tree); auth=auth, params = Dict(:recursive => true))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be worth only activating recursive in the subdir case? Otherwise there is no need to transfer all the deeper data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, probably good to limit the data transfer when it's not needed. Fixed in 06747a2

tree_sha = t.sha
project_files = joinpath.(subdir, Base.project_names)

for tr in t.tree, file in Base.project_names
if tr["path"] == file
for tr in t.tree, file in project_files
if tr["path"] == subdir
tree_sha = tr["sha"]
elseif tr["path"] == file
projectfile_found = true
@debug("(Julia)Project file found")

Expand All @@ -84,5 +88,5 @@ function verify_projectfile_from_sha(reponame, sha; auth=GitHub.AnonymousAuth())
end
end

return project, t.sha, projectfile_found, projectfile_valid, err
return project, tree_sha, projectfile_found, projectfile_valid, err
end