Skip to content

Instantly share code, notes, and snippets.

@mkitti
Created June 21, 2023 22:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mkitti/b8f6f0568122eabb234d9ce6011210e2 to your computer and use it in GitHub Desktop.
Save mkitti/b8f6f0568122eabb234d9ce6011210e2 to your computer and use it in GitHub Desktop.
Trigger Zenodo to detect old Github releases via Julia
#!/bin/env julia
# Inspired by https://github.com/zenodo/zenodo/issues/1463
module Zenodo
# Org/Repo, e.g. "JuliaMath/Interpolations.jl"
repo = ""
# This is a Zenodo API token that needs to be retrieved from Github webhooks
token = ""
# Setup environment
using Pkg
Pkg.activate(; temp = true)
Pkg.add(["HTTP", "JSON3", "Dates"])
using HTTP, JSON3, Dates
function collect_parameters(repo::AbstractString="", token::AbstractString="")
while isempty(repo)
println("Please enter the organization and repository name in the form Org/Repo (e.g. JuliaMath/Interpolations.jl):")
repo = readline()
repo = replace(repo, r"^https://github.com/" => "", r".git$" => "")
end
println("")
@info "Repository" repo
println("")
while isempty(token)
println("""
A Zenodo API token is needed, but it usually installed via webhook by Zenodo when adding a repository.
The token is contained at the end of the URL that starts with the following text.
https://zenodo.org/api/hooks/receivers/github/events/?access_token=
Visit https://github.com/$repo/settings/hooks to find this hook URL:
""")
token = readline()
token = replace(token, "https://zenodo.org/api/hooks/receivers/github/events/?access_token=" => "")
end
println("")
@info "Token" token
println("")
return repo, token
end
function collect_github_json(repo::AbstractString)
@info "Retrieving JSON from Github..."
# GitHub, also see GitHub.jl
github_headers = ["Accept" => "application/vnd.github.v3+json"]
# Get repository information
repo_response_string = String(HTTP.get("https://api.github.com/repos/$repo", github_headers).body)
repo_response_json = JSON3.read(repo_response_string)
@debug "Repository response" repo_response_json
# Get releases information
releases_response_string = String(HTTP.get("https://api.github.com/repos/$repo/releases", github_headers).body)
releases_response_json = JSON3.read(releases_response_string)
@debug "Releases response" releases_response_json
# Order releases from oldest to newest
datetimes = releases_response_json .|> x->DateTime(x[:created_at][1:end-1])
order = sortperm(datetimes)
releases_response_json = releases_response_json[order]
return repo_response_json, releases_response_json
end
# Trigger single release
function trigger_zenodo(repo_response_json::JSON3.Object, release_json::JSON3.Object, token::AbstractString)
try
@info "Release information" release_json[:name] release_json[:tag_name]
payload = Dict(
"action" => "published",
"release" => release_json,
"repository" => repo_response_json
)
submit_response = HTTP.post(
"https://zenodo.org/api/hooks/receivers/github/events/?access_token=$token",
["Content-Type" => "application/json"],
JSON3.write(payload)
)
println(submit_response)
catch err
if err isa HTTP.Exceptions.StatusError
error_response = JSON3.read(String(err.response.body))
@warn "An HTTP Status Error has occured" error_response
end
end
end
# Loop over multiple releases
function trigger_zenodo(repo_response_json::JSON3.Object, releases_response_json::Vector{JSON3.Object}, token::AbstractString)
for release_json in releases_response_json
trigger_zenodo(repo_response_json, release_json, token)
println()
println("Press enter to continue")
readline()
println()
end
end
function main()
global repo, token
repo, token = collect_parameters(repo, token)
repo_response_json, releases_response_json = collect_github_json(repo)
trigger_zenodo(repo_response_json, releases_response_json, token)
end
__init__() = @__FILE__() == abspath(PROGRAM_FILE) ? main() : println("Run Zenodo.main() to execute main program.")
end # module Zenodo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment