Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/GitForge.jl
Original file line number Diff line number Diff line change
Expand Up @@ -35,5 +35,6 @@ include("api.jl")
include(joinpath("forges", "GitHub", "GitHub.jl"))
include(joinpath("forges", "GitLab", "GitLab.jl"))
include(joinpath("forges", "Bitbucket", "Bitbucket.jl"))
include(joinpath("forges", "Codeberg", "Codeberg.jl"))

end
106 changes: 106 additions & 0 deletions src/forges/Codeberg/Codeberg.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
module Codeberg

import ..GitForge: endpoint, into, postprocessor, @forge

using ..GitForge
using ..GitForge:
@json,
AStr,
DoNothing,
DoSomething,
Endpoint,
Forge,
JSON,
OnRateLimit,
RateLimiter,
HEADERS,
ORL_THROW,
@not_implemented

using Dates
using HTTP
using JSON3: JSON3

export CodebergAPI, NoToken, Token

const DEFAULT_URL = "https://codeberg.org/api/v1"
const DEFAULT_DATEFORMAT = dateformat"yyyy-mm-ddTHH:MM:SS\Z"

abstract type AbstractToken end

"""
NoToken()

Represents no authentication.
Only public data will be available.
"""
struct NoToken <: AbstractToken end

"""
Token(token::$AStr)

A personal access token for Codeberg/Forgejo/Gitea.
"""
struct Token <: AbstractToken
token::String
end

auth_headers(::NoToken) = []
auth_headers(t::Token) = ["Authorization" => "token $(t.token)"]

"""
CodebergAPI(;
token::AbstractToken=NoToken(),
url::$AStr="$DEFAULT_URL",
has_rate_limits::Bool=false,
on_rate_limit::OnRateLimit=ORL_THROW,
)

Create a Codeberg/Forgejo/Gitea API client.

## Keywords
- `token::AbstractToken=NoToken()`: Authorization token (or lack thereof).
- `url::$AStr="$DEFAULT_URL"`: Base URL of the target instance.
- `has_rate_limits::Bool=false`: Whether or not the server has rate limits.
- `on_rate_limit::OnRateLimit=ORL_THROW`: Behaviour on exceeded rate limits.
"""
struct CodebergAPI <: Forge
token::AbstractToken
url::String
hasrl::Bool
orl::OnRateLimit
rl::RateLimiter

function CodebergAPI(;
token::AbstractToken=NoToken(),
url::AStr=DEFAULT_URL,
has_rate_limits::Bool=false,
on_rate_limit::OnRateLimit=ORL_THROW,
)
return new(token, url, has_rate_limits, on_rate_limit, RateLimiter())
end
end
@forge CodebergAPI

GitForge.base_url(c::CodebergAPI) = c.url
GitForge.request_headers(c::CodebergAPI, ::Function) = [HEADERS; auth_headers(c.token)]
GitForge.postprocessor(::CodebergAPI, ::Function) = JSON()
GitForge.has_rate_limits(c::CodebergAPI, ::Function) = c.hasrl
GitForge.rate_limit_check(c::CodebergAPI, ::Function) = GitForge.rate_limit_check(c.rl)
GitForge.on_rate_limit(c::CodebergAPI, ::Function) = c.orl
GitForge.rate_limit_wait(c::CodebergAPI, ::Function) = GitForge.rate_limit_wait(c.rl)
GitForge.rate_limit_period(c::CodebergAPI, ::Function) = GitForge.rate_limit_period(c.rl)
GitForge.rate_limit_update!(c::CodebergAPI, ::Function, r::HTTP.Response) =
GitForge.rate_limit_update!(c.rl, r)

include("users.jl")
include("repositories.jl")
include("pull_requests.jl")
include("commits.jl")
include("branches.jl")
include("tags.jl")
include("organizations.jl")

ismemberorcollaborator(r::HTTP.Response) = r.status == 204

end
59 changes: 59 additions & 0 deletions src/forges/Codeberg/branches.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
@json struct PayloadCommit
id::String
message::String
url::String
author::CommitUser
committer::CommitUser
timestamp::DateTime
end

@json struct BranchProtection
branch_name::String
enable_push::Bool
enable_push_whitelist::Bool
push_whitelist_usernames::Vector{String}
push_whitelist_teams::Vector{String}
push_whitelist_deploy_keys::Bool
enable_merge_whitelist::Bool
merge_whitelist_usernames::Vector{String}
merge_whitelist_teams::Vector{String}
enable_status_check::Bool
status_check_contexts::Vector{String}
required_approvals::Int
enable_approvals_whitelist::Bool
approvals_whitelist_usernames::Vector{String}
approvals_whitelist_teams::Vector{String}
block_on_rejected_reviews::Bool
block_on_official_review_requests::Bool
block_on_outdated_branch::Bool
dismiss_stale_approvals::Bool
require_signed_commits::Bool
protected_file_patterns::String
unprotected_file_patterns::String
created_at::DateTime
updated_at::DateTime
end

@json struct Branch
name::String
commit::PayloadCommit
protected::Bool
required_approvals::Int
enable_status_check::Bool
status_check_contexts::Vector{String}
user_can_push::Bool
user_can_merge::Bool
effective_branch_protection_name::String
end

endpoint(::CodebergAPI, ::typeof(get_branch), owner::AStr, repo::AStr, branch::AStr) =
Endpoint(:GET, "/repos/$owner/$repo/branches/$branch")
into(::CodebergAPI, ::typeof(get_branch)) = Branch

endpoint(::CodebergAPI, ::typeof(get_branches), owner::AStr, repo::AStr) =
Endpoint(:GET, "/repos/$owner/$repo/branches")
into(::CodebergAPI, ::typeof(get_branches)) = Vector{Branch}

endpoint(::CodebergAPI, ::typeof(delete_branch), owner::AStr, repo::AStr, branch::AStr) =
Endpoint(:DELETE, "/repos/$owner/$repo/branches/$branch")
postprocessor(::CodebergAPI, ::typeof(delete_branch)) = DoNothing()
41 changes: 41 additions & 0 deletions src/forges/Codeberg/commits.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
@json struct CommitUser
name::String
email::String
date::DateTime
end

@json struct RepoCommit
url::String
author::CommitUser
committer::CommitUser
message::String
end

@json struct CommitAffectedFiles
filename::String
status::String
end

@json struct CommitStats
total::Int
additions::Int
deletions::Int
end

@json struct Commit
url::String
sha::String
html_url::String
commit::RepoCommit
author::User
committer::User
parents::Vector{Commit}
files::Vector{CommitAffectedFiles}
stats::CommitStats
created::DateTime
end

endpoint(::CodebergAPI, ::typeof(get_commit), owner::AStr, repo::AStr, ref::AStr) =
Endpoint(:GET, "/repos/$owner/$repo/git/commits/$ref")
@not_implemented(::CodebergAPI, ::typeof(get_commit), ::Integer, ::String)
into(::CodebergAPI, ::typeof(get_commit)) = Commit
39 changes: 39 additions & 0 deletions src/forges/Codeberg/organizations.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
@json struct Organization
id::Int
name::String
full_name::String
email::String
avatar_url::String
description::String
website::String
location::String
visibility::String
repo_admin_change_team_access::Bool
username::String
end

endpoint(::CodebergAPI, ::typeof(is_member), org::AStr, user::AStr) =
Endpoint(:GET, "/orgs/$org/members/$user"; allow_404=true)
@not_implemented(::CodebergAPI, ::typeof(is_member), ::String, ::Integer)
postprocessor(::CodebergAPI, ::typeof(is_member)) = DoSomething(ismemberorcollaborator)
into(::CodebergAPI, ::typeof(is_member)) = Bool

@not_implemented(::CodebergAPI, ::typeof(groups))

@not_implemented(::CodebergAPI, ::typeof(list_pull_request_comments), ::String, ::String, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(list_pull_request_comments), ::Integer, ::Integer)

@not_implemented(::CodebergAPI, ::typeof(get_pull_request_comment), ::String, ::String, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(get_pull_request_comment), ::Integer, ::Integer, ::Integer)

@not_implemented(::CodebergAPI, ::typeof(create_pull_request_comment), ::String, ::String, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(create_pull_request_comment), ::Integer, ::Integer)

@not_implemented(::CodebergAPI, ::typeof(update_pull_request_comment), ::String, ::String, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(update_pull_request_comment), ::Integer, ::Integer, ::Integer)

@not_implemented(::CodebergAPI, ::typeof(delete_pull_request_comment), ::String, ::String, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(delete_pull_request_comment), ::Integer, ::Integer, ::Integer)

@not_implemented(::CodebergAPI, ::typeof(list_pipeline_schedules), ::Integer)
@not_implemented(::CodebergAPI, ::typeof(list_pipeline_schedules), ::String, ::String)
87 changes: 87 additions & 0 deletions src/forges/Codeberg/pull_requests.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
@json struct Label
id::Int
name::String
exclusive::Bool
is_archived::Bool
color::String
description::String
url::String
end

@json struct Milestone
id::Int
title::String
description::String
state::String
open_issues::Int
closed_issues::Int
created_at::DateTime
updated_at::DateTime
closed_at::DateTime
due_on::DateTime
end

@json struct PRBranchInfo
label::String
ref::String
sha::String
repo_id::Int
repo::Repo
end

@json struct PullRequest
id::Int
url::String
number::Int
user::User
title::String
body::String
labels::Vector{Label}
milestone::Milestone
assignee::User
assignees::Vector{User}
requested_reviewers::Vector{User}
state::String
is_locked::Bool
comments::Int
html_url::String
diff_url::String
patch_url::String
mergeable::Bool
merged::Bool
merged_at::DateTime
merge_commit_sha::String
merged_by::User
allow_maintainer_edit::Bool
base::PRBranchInfo
head::PRBranchInfo
merge_base::String
due_date::DateTime
created_at::DateTime
updated_at::DateTime
closed_at::DateTime
pin_order::Int
end

endpoint(::CodebergAPI, ::typeof(get_pull_requests), owner::AStr, repo::AStr) =
Endpoint(:GET, "/repos/$owner/$repo/pulls")
@not_implemented(::CodebergAPI, ::typeof(get_pull_requests), ::Integer)
into(::CodebergAPI, ::typeof(get_pull_requests)) = Vector{PullRequest}

endpoint(::CodebergAPI, ::typeof(get_pull_request), owner::AStr, repo::AStr, number::Integer) =
Endpoint(:GET, "/repos/$owner/$repo/pulls/$number")
@not_implemented(::CodebergAPI, ::typeof(get_pull_request), ::Integer, ::Integer)
into(::CodebergAPI, ::typeof(get_pull_request)) = PullRequest

endpoint(::CodebergAPI, ::typeof(create_pull_request), owner::AStr, repo::AStr) =
Endpoint(:POST, "/repos/$owner/$repo/pulls")
@not_implemented(::CodebergAPI, ::typeof(create_pull_request), ::Integer)
into(::CodebergAPI, ::typeof(create_pull_request)) = PullRequest

endpoint(::CodebergAPI, ::typeof(update_pull_request), owner::AStr, repo::AStr, number::Integer) =
Endpoint(:PATCH, "/repos/$owner/$repo/pulls/$number")
@not_implemented(::CodebergAPI, ::typeof(update_pull_request), ::Integer, ::Integer)
into(::CodebergAPI, ::typeof(update_pull_request)) = PullRequest

@not_implemented(::CodebergAPI, ::typeof(subscribe_to_pull_request), ::Integer, ::Integer)
@not_implemented(::CodebergAPI, ::typeof(unsubscribe_from_pull_request), ::Integer, ::Integer)
Loading
Loading