From ff252e0dab43088190bc089e91ef5604ae7d7750 Mon Sep 17 00:00:00 2001 From: Patrick Stevens <3138005+Smaug123@users.noreply.github.com> Date: Sun, 22 Sep 2024 16:50:32 +0100 Subject: [PATCH] Source-generate client (#92) --- Gitea.Declarative.Lib/Async.fs | 19 + Gitea.Declarative.Lib/ConfigSchema.fs | 134 +- .../GeneratedSwaggerGitea.fs | 6432 +++++++++++++++++ .../Gitea.Declarative.Lib.fsproj | 16 +- Gitea.Declarative.Lib/Gitea.fs | 746 +- Gitea.Declarative.Lib/GiteaClient.fs | 29 - Gitea.Declarative.Lib/IGiteaClient.fs | 90 - Gitea.Declarative.Lib/{Array.fs => List.fs} | 8 +- Gitea.Declarative.Lib/myriad.toml | 0 Gitea.Declarative.Test/TestRepo.fs | 65 +- Gitea.Declarative.Test/TestUser.fs | 8 +- Gitea.Declarative.Test/Utils.fs | 260 +- Gitea.Declarative/Reconcile.fs | 2 +- Gitea.Declarative/RefreshAuth.fs | 4 +- Gitea.InMemory/Client.fs | 63 +- Gitea.InMemory/Domain.fs | 105 - Gitea.InMemory/Server.fs | 37 +- README.md | 4 +- 18 files changed, 7303 insertions(+), 719 deletions(-) create mode 100644 Gitea.Declarative.Lib/GeneratedSwaggerGitea.fs delete mode 100644 Gitea.Declarative.Lib/GiteaClient.fs delete mode 100644 Gitea.Declarative.Lib/IGiteaClient.fs rename Gitea.Declarative.Lib/{Array.fs => List.fs} (61%) create mode 100644 Gitea.Declarative.Lib/myriad.toml diff --git a/Gitea.Declarative.Lib/Async.fs b/Gitea.Declarative.Lib/Async.fs index 2c35990..8b36c3a 100644 --- a/Gitea.Declarative.Lib/Async.fs +++ b/Gitea.Declarative.Lib/Async.fs @@ -1,5 +1,7 @@ namespace Gitea.Declarative +open System.Threading.Tasks + [] module Async = @@ -8,3 +10,20 @@ module Async = let! a = a return f a } + + /// The input function takes page first, then count. + /// Repeatedly calls `f` with increasing page numbers until all results are returned. + let getAllPaginated (f : int64 -> int64 -> 'ret array Task) : 'ret array Async = + let rec go (page : int64) (soFar : 'ret array) = + async { + let! newPage = f page 100L |> Async.AwaitTask + + let soFar = Array.append soFar newPage + + if newPage.Length < 100 then + return soFar + else + return! go (page + 1L) soFar + } + + go 0L [||] diff --git a/Gitea.Declarative.Lib/ConfigSchema.fs b/Gitea.Declarative.Lib/ConfigSchema.fs index f69c11a..d7a3395 100644 --- a/Gitea.Declarative.Lib/ConfigSchema.fs +++ b/Gitea.Declarative.Lib/ConfigSchema.fs @@ -240,48 +240,90 @@ type Repo = Native = this.Native |> Option.map (fun s -> s.OverrideDefaults ()) } - static member Render (client : IGiteaClient) (u : Gitea.Repository) : Repo Async = - if u.Mirror = Some true && not (String.IsNullOrEmpty u.OriginalUrl) then + static member Render (client : GiteaClient.IGiteaClient) (u : GiteaClient.Repository) : Repo Async = + match u.Mirror, u.OriginalUrl with + | Some true, Some originalUrl when originalUrl <> "" -> { - Description = u.Description + Description = + match u.Description with + | None -> "(no description)" + | Some d -> d GitHub = { - Uri = Uri u.OriginalUrl - MirrorInterval = u.MirrorInterval + Uri = Uri originalUrl + MirrorInterval = + match u.MirrorInterval with + | None -> "8h0m0s" + | Some s -> s } |> Some Native = None Deleted = None } |> async.Return - else - let repoFullName = u.FullName + | _, _ -> + let repoFullName = + match u.FullName with + | None -> failwith "Repo unexpectedly had no full name!" + | Some f -> f async { - let owner = u.Owner + let owner = + match u.Owner with + | None -> failwith "Gitea unexpectedly gave us a repository with no owner!" + | Some owner -> owner - let loginName = owner.LoginName + let loginName = + match owner.LoginName with + | None -> failwith "Owner of repo unexpectedly had no login name!" + | Some n -> n let! mirrors = - getAllPaginated (fun page count -> - client.RepoListPushMirrors (loginName, repoFullName, Some page, Some count) + List.getPaginated (fun page count -> + async { + let! ct = Async.CancellationToken + + return! + client.RepoListPushMirrors (loginName, repoFullName, page, count, ct) + |> Async.AwaitTask + } ) - let! (branchProtections : Gitea.BranchProtection[]) = - client.RepoListBranchProtection (u.Owner.LoginName, u.FullName) - |> Async.AwaitTask + let! (branchProtections : GiteaClient.BranchProtection list) = + async { + let! ct = Async.CancellationToken + return! client.RepoListBranchProtection (loginName, repoFullName, ct) |> Async.AwaitTask + } - let! (collaborators : Gitea.User[]) = - getAllPaginated (fun page count -> - client.RepoListCollaborators (u.Owner.LoginName, u.FullName, Some page, Some count) + let! (collaborators : GiteaClient.User list) = + List.getPaginated (fun page count -> + async { + let! ct = Async.CancellationToken + + return! + client.RepoListCollaborators (loginName, repoFullName, page, count, ct) + |> Async.AwaitTask + } ) - let defaultBranch = u.DefaultBranch + let defaultBranch = + match u.DefaultBranch with + | None -> failwith "repo unexpectedly had no default branch!" + | Some d -> d let collaborators = - collaborators |> Seq.map (fun user -> user.LoginName) |> Set.ofSeq + collaborators + |> Seq.map (fun user -> + match user.LoginName with + | None -> failwith "user unexpectedly had no login name!" + | Some n -> n + ) + |> Set.ofSeq - let description = u.Description + let description = + match u.Description with + | None -> failwith "Unexpectedly got no description on a repo!" + | Some d -> d return @@ -298,7 +340,7 @@ type Repo = HasProjects = u.HasProjects HasIssues = u.HasIssues HasWiki = u.HasWiki - DefaultMergeStyle = u.DefaultMergeStyle |> Option.ofObj |> Option.map MergeStyle.Parse + DefaultMergeStyle = u.DefaultMergeStyle |> Option.map MergeStyle.Parse DeleteBranchAfterMerge = u.DefaultDeleteBranchAfterMerge AllowSquashMerge = u.AllowSquashMerge AllowRebaseUpdate = u.AllowRebaseUpdate @@ -307,22 +349,30 @@ type Repo = AllowMergeCommits = u.AllowMergeCommits Mirrors = mirrors - |> Array.toList |> List.map (fun m -> - { - GitHubAddress = Uri m.RemoteAddress - RemoteName = Some m.RemoteName - } + match m.RemoteAddress, m.RemoteName with + | None, _ -> failwith "Unexpectedly have a PushMirror but no remote address!" + | Some _, None -> + failwith "Unexpectedly have a PushMirror with no remote name!" + | Some s, Some remoteName -> + { + GitHubAddress = Uri s + RemoteName = Some remoteName + } ) ProtectedBranches = branchProtections |> Seq.map (fun bp -> + match bp.BranchName with + | None -> failwith "Unexpectedly have a BranchProtection with no branch name!" + | Some branchName -> + { - BranchName = bp.BranchName + BranchName = branchName BlockOnOutdatedBranch = bp.BlockOnOutdatedBranch RequiredStatusChecks = if bp.EnableStatusCheck = Some true then - bp.StatusCheckContexts |> List.ofArray |> Some + bp.StatusCheckContexts else None } @@ -373,20 +423,24 @@ type UserInfo = Visibility : string option } - static member Render (u : Gitea.User) : UserInfo = + static member Render (u : GiteaClient.User) : UserInfo = + let website = + u.Website + |> Option.bind (fun ws -> + match Uri.TryCreate (ws, UriKind.Absolute) with + | false, _ -> None + | true, uri -> Some uri + ) + + let email = + u.Email + |> Option.defaultWith (fun () -> failwith "Gitea user failed to have an email!") + { IsAdmin = u.IsAdmin - Email = u.Email - Website = - if String.IsNullOrEmpty u.Website then - None - else - Some (Uri u.Website) - Visibility = - if String.IsNullOrEmpty u.Visibility then - None - else - Some u.Visibility + Email = email + Website = website + Visibility = u.Visibility } static member internal OfSerialised (s : SerialisedUserInfo) = diff --git a/Gitea.Declarative.Lib/GeneratedSwaggerGitea.fs b/Gitea.Declarative.Lib/GeneratedSwaggerGitea.fs new file mode 100644 index 0000000..4437d2b --- /dev/null +++ b/Gitea.Declarative.Lib/GeneratedSwaggerGitea.fs @@ -0,0 +1,6432 @@ +//------------------------------------------------------------------------------ +// This code was generated by myriad. +// Changes to this file will be lost when the code is regenerated. +//------------------------------------------------------------------------------ + + + + + + + +namespace GiteaClient + +open WoofWare.Myriad.Plugins + +/// APIError is an api error with a message +[] +type APIError = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Message : string option + [] + Url : string option + } + +/// AccessToken represents an API access token. +[] +type AccessToken = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Id : int option + [] + Name : string option + [] + Scopes : string list option + [] + Sha1 : string option + [] + TokenLastEight : string option + } + +/// ActivityPub type +[] +type ActivityPub = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Context : string option + } + +/// AddCollaboratorOption options when adding a user as a collaborator of a repository +[] +type AddCollaboratorOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Permission : string option + } + +/// AddTimeOption options for adding time to an issue +[] +type AddTimeOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Time : int + [] + UserName : string option + } + +/// AnnotatedTagObject contains meta information of the tag object +[] +type AnnotatedTagObject = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Sha : string option + [] + Type : string option + [] + Url : string option + } + +/// Attachment a generic attachment +[] +type Attachment = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + BrowserDownloadUrl : string option + [] + CreatedAt : string option + [] + DownloadCount : int option + [] + Id : int option + [] + Name : string option + [] + Size : int option + [] + Uuid : string option + } + +/// BranchProtection represents a branch protection for a repository +[] +type BranchProtection = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ApprovalsWhitelistTeams : string list option + [] + ApprovalsWhitelistUsername : string list option + [] + BlockOnOfficialReviewRequests : bool option + [] + BlockOnOutdatedBranch : bool option + [] + BlockOnRejectedReviews : bool option + [] + BranchName : string option + [] + CreatedAt : string option + [] + DismissStaleApprovals : bool option + [] + EnableApprovalsWhitelist : bool option + [] + EnableMergeWhitelist : bool option + [] + EnablePush : bool option + [] + EnablePushWhitelist : bool option + [] + EnableStatusCheck : bool option + [] + MergeWhitelistTeams : string list option + [] + MergeWhitelistUsernames : string list option + [] + ProtectedFilePatterns : string option + [] + PushWhitelistDeployKeys : bool option + [] + PushWhitelistTeams : string list option + [] + PushWhitelistUsernames : string list option + [] + RequireSignedCommits : bool option + [] + RequiredApprovals : int option + [] + RuleName : string option + [] + StatusCheckContexts : string list option + [] + UnprotectedFilePatterns : string option + [] + UpdatedAt : string option + } + +/// ChangedFile store information about files affected by the pull request +[] +type ChangedFile = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Additions : int option + [] + Changes : int option + [] + ContentsUrl : string option + [] + Deletions : int option + [] + Filename : string option + [] + HtmlUrl : string option + [] + PreviousFilename : string option + [] + RawUrl : string option + [] + Status : string option + } + +/// CommitAffectedFiles store information about files affected by the commit +[] +type CommitAffectedFiles = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Filename : string option + } + +/// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE +[] +type CommitDateOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : string option + [] + Committer : string option + } + +/// CommitMeta contains meta information of a commit in terms of API. +[] +type CommitMeta = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Sha : string option + [] + Url : string option + } + +/// CommitStats is statistics for a RepoCommit +[] +type CommitStats = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Additions : int option + [] + Deletions : int option + [] + Total : int option + } + +/// CommitUser contains information of a user in the context of a commit. +[] +type CommitUser = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Date : string option + [] + Email : string option + [] + Name : string option + } + +/// CreateAccessTokenOption options when create access token +[] +type CreateAccessTokenOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Name : string + [] + Scopes : string list option + } + +/// CreateBranchProtectionOption options for creating a branch protection +[] +type CreateBranchProtectionOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ApprovalsWhitelistTeams : string list option + [] + ApprovalsWhitelistUsername : string list option + [] + BlockOnOfficialReviewRequests : bool option + [] + BlockOnOutdatedBranch : bool option + [] + BlockOnRejectedReviews : bool option + [] + BranchName : string option + [] + DismissStaleApprovals : bool option + [] + EnableApprovalsWhitelist : bool option + [] + EnableMergeWhitelist : bool option + [] + EnablePush : bool option + [] + EnablePushWhitelist : bool option + [] + EnableStatusCheck : bool option + [] + MergeWhitelistTeams : string list option + [] + MergeWhitelistUsernames : string list option + [] + ProtectedFilePatterns : string option + [] + PushWhitelistDeployKeys : bool option + [] + PushWhitelistTeams : string list option + [] + PushWhitelistUsernames : string list option + [] + RequireSignedCommits : bool option + [] + RequiredApprovals : int option + [] + RuleName : string option + [] + StatusCheckContexts : string list option + [] + UnprotectedFilePatterns : string option + } + +/// CreateBranchRepoOption options when creating a branch in a repository +[] +type CreateBranchRepoOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + NewBranchName : string + [] + OldBranchName : string option + } + +/// CreateEmailOption options when creating email addresses +[] +type CreateEmailOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Emails : string list option + } + +/// CreateForkOption options for creating a fork +[] +type CreateForkOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Name : string option + [] + Organization : string option + } + +/// CreateGPGKeyOption options create user GPG key +[] +type CreateGPGKeyOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ArmoredPublicKey : string + [] + ArmoredSignature : string option + } + +/// CreateHookOptionConfig has all config options in it +/// required are "content_type" and "url" Required +[] +type CreateHookOptionConfig = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// CreateIssueCommentOption options for creating a comment on an issue +[] +type CreateIssueCommentOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string + } + +/// CreateIssueOption options to create one issue +[] +type CreateIssueOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assignee : string option + [] + Assignees : string list option + [] + Body : string option + [] + Closed : bool option + [] + DueDate : string option + [] + Labels : int list option + [] + Milestone : int option + [] + Ref : string option + [] + Title : string + } + +/// CreateKeyOption options when creating a key +[] +type CreateKeyOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Key : string + [] + ReadOnly : bool option + [] + Title : string + } + +/// CreateLabelOption options for creating a label +[] +type CreateLabelOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Color : string + [] + Description : string option + [] + Exclusive : bool option + [] + Name : string + } + +/// CreateMilestoneOption options for creating a milestone +[] +type CreateMilestoneOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + DueOn : string option + [] + State : string option + [] + Title : string option + } + +/// CreateOAuth2ApplicationOptions holds options to create an oauth2 application +[] +type CreateOAuth2ApplicationOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ConfidentialClient : bool option + [] + Name : string option + [] + RedirectUris : string list option + } + +/// CreateOrgOption options for creating an organization +[] +type CreateOrgOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + FullName : string option + [] + Location : string option + [] + RepoAdminChangeTeamAccess : bool option + [] + Username : string + [] + Visibility : string option + [] + Website : string option + } + +/// CreatePullRequestOption options when creating a pull request +[] +type CreatePullRequestOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assignee : string option + [] + Assignees : string list option + [] + Base : string option + [] + Body : string option + [] + DueDate : string option + [] + Head : string option + [] + Labels : int list option + [] + Milestone : int option + [] + Title : string option + } + +/// CreatePullReviewComment represent a review comment for creation api +[] +type CreatePullReviewComment = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + NewPosition : int option + [] + OldPosition : int option + [] + Path : string option + } + +/// CreatePushMirrorOption represents need information to create a push mirror of a repository. +[] +type CreatePushMirrorOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Interval : string option + [] + RemoteAddress : string option + [] + RemotePassword : string option + [] + RemoteUsername : string option + [] + SyncOnCommit : bool option + } + +/// CreateReleaseOption options when creating a release +[] +type CreateReleaseOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + Draft : bool option + [] + Name : string option + [] + Prerelease : bool option + [] + TagName : string + [] + TargetCommitish : string option + } + +/// CreateRepoOption options when creating repository +[] +type CreateRepoOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AutoInit : bool option + [] + DefaultBranch : string option + [] + Description : string option + [] + Gitignores : string option + [] + IssueLabels : string option + [] + License : string option + [] + Name : string + [] + Private : bool option + [] + Readme : string option + [] + Template : bool option + [] + TrustModel : string option + } + +/// CreateStatusOption holds the information needed to create a new CommitStatus for a Commit +[] +type CreateStatusOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Context : string option + [] + Description : string option + [] + State : string option + [] + TargetUrl : string option + } + +/// CreateTagOption options when creating a tag +[] +type CreateTagOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Message : string option + [] + TagName : string + [] + Target : string option + } + +[] +type Type1 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// CreateTeamOption options for creating a team +[] +type CreateTeamOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CanCreateOrgRepo : bool option + [] + Description : string option + [] + IncludesAllRepositories : bool option + [] + Name : string + [] + Permission : string option + [] + Units : string list option + [] + UnitsMap : Type1 option + } + +/// CreateUserOption create user options +[] +type CreateUserOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CreatedAt : string option + [] + Email : string + [] + FullName : string option + [] + LoginName : string option + [] + MustChangePassword : bool option + [] + Password : string + [] + Restricted : bool option + [] + SendNotify : bool option + [] + SourceId : int option + [] + Username : string + [] + Visibility : string option + } + +/// CreateWikiPageOptions form for creating wiki +[] +type CreateWikiPageOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ContentBase64 : string option + [] + Message : string option + [] + Title : string option + } + +/// Cron represents a Cron task +[] +type Cron = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ExecTimes : int option + [] + Name : string option + [] + Next : string option + [] + Prev : string option + [] + Schedule : string option + } + +/// DeleteEmailOption options when deleting email addresses +[] +type DeleteEmailOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Emails : string list option + } + +/// DismissPullReviewOptions are options to dismiss a pull review +[] +type DismissPullReviewOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Message : string option + [] + Priors : bool option + } + +/// EditAttachmentOptions options for editing attachments +[] +type EditAttachmentOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Name : string option + } + +/// EditBranchProtectionOption options for editing a branch protection +[] +type EditBranchProtectionOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ApprovalsWhitelistTeams : string list option + [] + ApprovalsWhitelistUsername : string list option + [] + BlockOnOfficialReviewRequests : bool option + [] + BlockOnOutdatedBranch : bool option + [] + BlockOnRejectedReviews : bool option + [] + DismissStaleApprovals : bool option + [] + EnableApprovalsWhitelist : bool option + [] + EnableMergeWhitelist : bool option + [] + EnablePush : bool option + [] + EnablePushWhitelist : bool option + [] + EnableStatusCheck : bool option + [] + MergeWhitelistTeams : string list option + [] + MergeWhitelistUsernames : string list option + [] + ProtectedFilePatterns : string option + [] + PushWhitelistDeployKeys : bool option + [] + PushWhitelistTeams : string list option + [] + PushWhitelistUsernames : string list option + [] + RequireSignedCommits : bool option + [] + RequiredApprovals : int option + [] + StatusCheckContexts : string list option + [] + UnprotectedFilePatterns : string option + } + +/// EditDeadlineOption options for creating a deadline +[] +type EditDeadlineOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + DueDate : string + } + +/// EditGitHookOption options when modifying one Git hook +[] +type EditGitHookOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Content : string option + } + +[] +type Type2 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// EditHookOption options when modify one hook +[] +type EditHookOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Active : bool option + [] + AuthorizationHeader : string option + [] + BranchFilter : string option + [] + Config : Type2 option + [] + Events : string list option + } + +/// EditIssueCommentOption options for editing a comment +[] +type EditIssueCommentOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string + } + +/// EditIssueOption options for editing an issue +[] +type EditIssueOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assignee : string option + [] + Assignees : string list option + [] + Body : string option + [] + DueDate : string option + [] + Milestone : int option + [] + Ref : string option + [] + State : string option + [] + Title : string option + [] + UnsetDueDate : bool option + } + +/// EditLabelOption options for editing a label +[] +type EditLabelOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Color : string option + [] + Description : string option + [] + Exclusive : bool option + [] + Name : string option + } + +/// EditMilestoneOption options for editing a milestone +[] +type EditMilestoneOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + DueOn : string option + [] + State : string option + [] + Title : string option + } + +/// EditOrgOption options for editing an organization +[] +type EditOrgOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + FullName : string option + [] + Location : string option + [] + RepoAdminChangeTeamAccess : bool option + [] + Visibility : string option + [] + Website : string option + } + +/// EditPullRequestOption options when modify pull request +[] +type EditPullRequestOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowMaintainerEdit : bool option + [] + Assignee : string option + [] + Assignees : string list option + [] + Base : string option + [] + Body : string option + [] + DueDate : string option + [] + Labels : int list option + [] + Milestone : int option + [] + State : string option + [] + Title : string option + [] + UnsetDueDate : bool option + } + +/// EditReactionOption contain the reaction type +[] +type EditReactionOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Content : string option + } + +/// EditReleaseOption options when editing a release +[] +type EditReleaseOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + Draft : bool option + [] + Name : string option + [] + Prerelease : bool option + [] + TagName : string option + [] + TargetCommitish : string option + } + +[] +type Type3 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// EditTeamOption options for editing a team +[] +type EditTeamOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CanCreateOrgRepo : bool option + [] + Description : string option + [] + IncludesAllRepositories : bool option + [] + Name : string + [] + Permission : string option + [] + Units : string list option + [] + UnitsMap : Type3 option + } + +/// EditUserOption edit user options +[] +type EditUserOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Active : bool option + [] + Admin : bool option + [] + AllowCreateOrganization : bool option + [] + AllowGitHook : bool option + [] + AllowImportLocal : bool option + [] + Description : string option + [] + Email : string option + [] + FullName : string option + [] + Location : string option + [] + LoginName : string + [] + MaxRepoCreation : int option + [] + MustChangePassword : bool option + [] + Password : string option + [] + ProhibitLogin : bool option + [] + Restricted : bool option + [] + SourceId : int + [] + Visibility : string option + [] + Website : string option + } + +/// Email an email address belonging to a user +[] +type Email = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Email : string option + [] + Primary : bool option + [] + Verified : bool option + } + +/// ExternalTracker represents settings for external tracker +[] +type ExternalTracker = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ExternalTrackerFormat : string option + [] + ExternalTrackerRegexpPattern : string option + [] + ExternalTrackerStyle : string option + [] + ExternalTrackerUrl : string option + } + +/// ExternalWiki represents setting for external wiki +[] +type ExternalWiki = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ExternalWikiUrl : string option + } + +/// FileCommitResponse contains information generated from a Git commit for a repo's file. +[] +type FileCommitResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : CommitUser option + [] + Committer : CommitUser option + [] + Created : string option + [] + HtmlUrl : string option + [] + Message : string option + [] + Parents : CommitMeta list option + [] + Sha : string option + [] + Tree : CommitMeta option + [] + Url : string option + } + +/// FileLinksResponse contains the links for a repo's file +[] +type FileLinksResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Git : string option + [] + Html : string option + [] + Self : string option + } + +/// GPGKeyEmail an email attached to a GPGKey +[] +type GPGKeyEmail = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Email : string option + [] + Verified : bool option + } + +/// GeneralAPISettings contains global api settings exposed by it +[] +type GeneralAPISettings = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + DefaultGitTreesPerPage : int option + [] + DefaultMaxBlobSize : int option + [] + DefaultPagingNum : int option + [] + MaxResponseItems : int option + } + +/// GeneralAttachmentSettings contains global Attachment settings exposed by API +[] +type GeneralAttachmentSettings = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowedTypes : string option + [] + Enabled : bool option + [] + MaxFiles : int option + [] + MaxSize : int option + } + +/// GeneralRepoSettings contains global repository settings exposed by API +[] +type GeneralRepoSettings = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + HttpGitDisabled : bool option + [] + LfsDisabled : bool option + [] + MigrationsDisabled : bool option + [] + MirrorsDisabled : bool option + [] + StarsDisabled : bool option + [] + TimeTrackingDisabled : bool option + } + +/// GeneralUISettings contains global ui settings exposed by API +[] +type GeneralUISettings = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowedReactions : string list option + [] + CustomEmojis : string list option + [] + DefaultTheme : string option + } + +/// GenerateRepoOption options when creating repository using a template +[] +type GenerateRepoOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Avatar : bool option + [] + DefaultBranch : string option + [] + Description : string option + [] + GitContent : bool option + [] + GitHooks : bool option + [] + Labels : bool option + [] + Name : string + [] + Owner : string + [] + Private : bool option + [] + Topics : bool option + [] + Webhooks : bool option + } + +/// GitBlobResponse represents a git blob +[] +type GitBlobResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Content : string option + [] + Encoding : string option + [] + Sha : string option + [] + Size : int option + [] + Url : string option + } + +/// GitEntry represents a git tree +[] +type GitEntry = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Mode : string option + [] + Path : string option + [] + Sha : string option + [] + Size : int option + [] + Type : string option + [] + Url : string option + } + +/// GitHook represents a Git repository hook +[] +type GitHook = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Content : string option + [] + IsActive : bool option + [] + Name : string option + } + +/// GitObject represents a Git object. +[] +type GitObject = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Sha : string option + [] + Type : string option + [] + Url : string option + } + +/// GitTreeResponse returns a git tree +[] +type GitTreeResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Page : int option + [] + Sha : string option + [] + TotalCount : int option + [] + Tree : GitEntry list option + [] + Truncated : bool option + [] + Url : string option + } + +[] +type Type4 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// Hook a hook is a web hook when one repository changed +[] +type Hook = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Active : bool option + [] + AuthorizationHeader : string option + [] + Config : Type4 option + [] + CreatedAt : string option + [] + Events : string list option + [] + Id : int option + [] + Type : string option + [] + UpdatedAt : string option + } + +/// Identity for a person's identity like an author or committer +[] +type Identity = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Email : string option + [] + Name : string option + } + +/// InternalTracker represents settings for internal tracker +[] +type InternalTracker = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowOnlyContributorsToTrackTime : bool option + [] + EnableIssueDependencies : bool option + [] + EnableTimeTracker : bool option + } + +/// IssueDeadline represents an issue deadline +[] +type IssueDeadline = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + DueDate : string option + } + +[] +type Type5 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +[] +type Type6 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// IssueLabelsOption a collection of labels +[] +type IssueLabelsOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Labels : int list option + } + +/// Label a label to an issue or a pr +[] +type Label = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Color : string option + [] + Description : string option + [] + Exclusive : bool option + [] + Id : int option + [] + Name : string option + [] + Url : string option + } + +/// MarkdownOption markdown options +[] +type MarkdownOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Context : string option + [] + Mode : string option + [] + Text : string option + [] + Wiki : bool option + } + +/// MergePullRequestForm form for merging Pull Request +[] +type MergePullRequestOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Do : string + [] + MergeCommitID : string option + [] + MergeMessageField : string option + [] + MergeTitleField : string option + [] + DeleteBranchAfterMerge : bool option + [] + ForceMerge : bool option + [] + HeadCommitId : string option + [] + MergeWhenChecksSucceed : bool option + } + +/// MigrateRepoOptions options for migrating repository's +/// this is used to interact with api v1 +[] +type MigrateRepoOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AuthPassword : string option + [] + AuthToken : string option + [] + AuthUsername : string option + [] + CloneAddr : string + [] + Description : string option + [] + Issues : bool option + [] + Labels : bool option + [] + Lfs : bool option + [] + LfsEndpoint : string option + [] + Milestones : bool option + [] + Mirror : bool option + [] + MirrorInterval : string option + [] + Private : bool option + [] + PullRequests : bool option + [] + Releases : bool option + [] + RepoName : string + [] + RepoOwner : string option + [] + Service : string option + [] + Uid : int option + [] + Wiki : bool option + } + +[] +type Type7 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// NodeInfoServices contains the third party sites this server can connect to via their application API +[] +type NodeInfoServices = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Inbound : string list option + [] + Outbound : string list option + } + +/// NodeInfoSoftware contains Metadata about server software in use +[] +type NodeInfoSoftware = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Homepage : string option + [] + Name : string option + [] + Repository : string option + [] + Version : string option + } + +/// NodeInfoUsageUsers contains statistics about the users of this server +[] +type NodeInfoUsageUsers = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ActiveHalfyear : int option + [] + ActiveMonth : int option + [] + Total : int option + } + +/// NotificationCount number of unread notifications +[] +type NotificationCount = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + New : int option + } + +/// OAuth2Application represents an OAuth2 application. +[] +type OAuth2Application = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ClientId : string option + [] + ClientSecret : string option + [] + ConfidentialClient : bool option + [] + Created : string option + [] + Id : int option + [] + Name : string option + [] + RedirectUris : string list option + } + +/// Organization represents an organization +[] +type Organization = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AvatarUrl : string option + [] + Description : string option + [] + FullName : string option + [] + Id : int option + [] + Location : string option + [] + Name : string option + [] + RepoAdminChangeTeamAccess : bool option + [] + Username : string option + [] + Visibility : string option + [] + Website : string option + } + +/// OrganizationPermissions list different users permissions on an organization +[] +type OrganizationPermissions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CanCreateRepository : bool option + [] + CanRead : bool option + [] + CanWrite : bool option + [] + IsAdmin : bool option + [] + IsOwner : bool option + } + +/// PackageFile represents a package file +[] +type PackageFile = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Size : int option + [] + Id : int option + [] + Md5 : string option + [] + Name : string option + [] + Sha1 : string option + [] + Sha256 : string option + [] + Sha512 : string option + } + +/// PayloadUser represents the author or committer of a commit +[] +type PayloadUser = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Email : string option + [] + Name : string option + [] + Username : string option + } + +/// Permission represents a set of permissions +[] +type Permission = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Admin : bool option + [] + Pull : bool option + [] + Push : bool option + } + +/// PullRequestMeta PR info if an issue is a PR +[] +type PullRequestMeta = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Merged : bool option + [] + MergedAt : string option + } + +/// PullReviewRequestOptions are options to add or remove pull review requests +[] +type PullReviewRequestOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Reviewers : string list option + [] + TeamReviewers : string list option + } + +/// PushMirror represents information of a push mirror +[] +type PushMirror = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Interval : string option + [] + LastError : string option + [] + LastUpdate : string option + [] + RemoteAddress : string option + [] + RemoteName : string option + [] + RepoName : string option + [] + SyncOnCommit : bool option + } + +/// Reference represents a Git reference. +[] +type Reference = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Object : GitObject option + [] + Ref : string option + [] + Url : string option + } + +/// RepoTopicOptions a collection of repo topic names +[] +type RepoTopicOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Topics : string list option + } + +/// RepositoryMeta basic repository information +[] +type RepositoryMeta = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + FullName : string option + [] + Id : int option + [] + Name : string option + [] + Owner : string option + } + +/// ServerVersion wraps the version of the server +[] +type ServerVersion = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Version : string option + } + +/// StopWatch represent a running stopwatch +[] +type StopWatch = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Duration : string option + [] + IssueIndex : int option + [] + IssueTitle : string option + [] + RepoName : string option + [] + RepoOwnerName : string option + [] + Seconds : int option + } + +/// SubmitPullReviewOptions are options to submit a pending pull review +[] +type SubmitPullReviewOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + Event : string option + } + +/// Tag represents a repository tag +[] +type Tag = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commit : CommitMeta option + [] + Id : string option + [] + Message : string option + [] + Name : string option + [] + TarballUrl : string option + [] + ZipballUrl : string option + } + +[] +type Type8 = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// Team represents a team in an organization +[] +type Team = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CanCreateOrgRepo : bool option + [] + Description : string option + [] + Id : int option + [] + IncludesAllRepositories : bool option + [] + Name : string option + [] + Organization : Organization option + [] + Permission : string option + [] + Units : string list option + [] + UnitsMap : Type8 option + } + +/// TopicName a list of repo topic names +[] +type TopicName = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Topics : string list option + } + +/// TopicResponse for returning topics +[] +type TopicResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Id : int option + [] + RepoCount : int option + [] + TopicName : string option + [] + Updated : string option + } + +/// TransferRepoOption options when transfer a repository's ownership +[] +type TransferRepoOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + NewOwner : string + [] + TeamIds : int list option + } + +/// UpdateFileOptions options for updating files +/// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +[] +type UpdateFileOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : Identity option + [] + Branch : string option + [] + Committer : Identity option + [] + Content : string + [] + Dates : CommitDateOptions option + [] + FromPath : string option + [] + Message : string option + [] + NewBranch : string option + [] + Sha : string + [] + Signoff : bool option + } + +/// User represents a user +[] +type User = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Active : bool option + [] + AvatarUrl : string option + [] + Created : string option + [] + Description : string option + [] + Email : string option + [] + FollowersCount : int option + [] + FollowingCount : int option + [] + FullName : string option + [] + Id : int option + [] + IsAdmin : bool option + [] + Language : string option + [] + LastLogin : string option + [] + Location : string option + [] + Login : string option + [] + LoginName : string option + [] + ProhibitLogin : bool option + [] + Restricted : bool option + [] + StarredReposCount : int option + [] + Visibility : string option + [] + Website : string option + } + +/// UserHeatmapData represents the data needed to create a heatmap +[] +type UserHeatmapData = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Contributions : int option + [] + Timestamp : int option + } + +/// UserSettings represents user settings +[] +type UserSettings = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + DiffViewStyle : string option + [] + FullName : string option + [] + HideActivity : bool option + [] + HideEmail : bool option + [] + Language : string option + [] + Location : string option + [] + Theme : string option + [] + Website : string option + } + +/// UserSettingsOptions represents options to change user settings +[] +type UserSettingsOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Description : string option + [] + DiffViewStyle : string option + [] + FullName : string option + [] + HideActivity : bool option + [] + HideEmail : bool option + [] + Language : string option + [] + Location : string option + [] + Theme : string option + [] + Website : string option + } + +/// WatchInfo represents an API watch status of one repository +[] +type WatchInfo = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CreatedAt : string option + [] + Ignored : bool option + [] + Reason : unit option + [] + RepositoryUrl : string option + [] + Subscribed : bool option + [] + Url : string option + } + +/// WikiCommit page commit/revision +[] +type WikiCommit = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : CommitUser option + [] + Commiter : CommitUser option + [] + Message : string option + [] + Sha : string option + } + +/// WikiCommitList commit/revision list +[] +type WikiCommitList = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commits : WikiCommit list option + [] + Count : int option + } + +/// WikiPage a wiki page +[] +type WikiPage = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CommitCount : int option + [] + ContentBase64 : string option + [] + Footer : string option + [] + HtmlUrl : string option + [] + LastCommit : WikiCommit option + [] + Sidebar : string option + [] + SubUrl : string option + [] + Title : string option + } + +/// WikiPageMetaData wiki page meta information +[] +type WikiPageMetaData = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + HtmlUrl : string option + [] + LastCommit : WikiCommit option + [] + SubUrl : string option + [] + Title : string option + } + +/// Comment represents a comment on a commit or issue +[] +type Comment = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assets : Attachment list option + [] + Body : string option + [] + CreatedAt : string option + [] + HtmlUrl : string option + [] + Id : int option + [] + IssueUrl : string option + [] + OriginalAuthor : string option + [] + OriginalAuthorId : int option + [] + PullRequestUrl : string option + [] + UpdatedAt : string option + [] + User : User option + } + +/// CommitStatus holds a single status of a single Commit +[] +type CommitStatus = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Context : string option + [] + CreatedAt : string option + [] + Creator : User option + [] + Description : string option + [] + Id : int option + [] + Status : string option + [] + TargetUrl : string option + [] + UpdatedAt : string option + [] + Url : string option + } + +/// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content +[] +type ContentsResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Links : FileLinksResponse option + [] + Content : string option + [] + DownloadUrl : string option + [] + Encoding : string option + [] + GitUrl : string option + [] + HtmlUrl : string option + [] + LastCommitSha : string option + [] + Name : string option + [] + Path : string option + [] + Sha : string option + [] + Size : int option + [] + SubmoduleGitUrl : string option + [] + Target : string option + [] + Type : string option + [] + Url : string option + } + +/// CreateFileOptions options for creating files +/// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +[] +type CreateFileOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : Identity option + [] + Branch : string option + [] + Committer : Identity option + [] + Content : string + [] + Dates : CommitDateOptions option + [] + Message : string option + [] + NewBranch : string option + [] + Signoff : bool option + } + +/// CreateHookOption options when create a hook +[] +type CreateHookOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Active : bool option + [] + AuthorizationHeader : string option + [] + BranchFilter : string option + [] + Config : CreateHookOptionConfig + [] + Events : string list option + [] + Type : string + } + +/// CreatePullReviewOptions are options to create a pull review +[] +type CreatePullReviewOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + Comments : CreatePullReviewComment list option + [] + CommitId : string option + [] + Event : string option + } + +/// DeleteFileOptions options for deleting files (used for other File structs below) +/// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used) +[] +type DeleteFileOptions = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : Identity option + [] + Branch : string option + [] + Committer : Identity option + [] + Dates : CommitDateOptions option + [] + Message : string option + [] + NewBranch : string option + [] + Sha : string + [] + Signoff : bool option + } + +/// EditRepoOption options when editing a repository's properties +[] +type EditRepoOption = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowManualMerge : bool option + [] + AllowMergeCommits : bool option + [] + AllowRebase : bool option + [] + AllowRebaseExplicit : bool option + [] + AllowRebaseUpdate : bool option + [] + AllowSquashMerge : bool option + [] + Archived : bool option + [] + AutodetectManualMerge : bool option + [] + DefaultAllowMaintainerEdit : bool option + [] + DefaultBranch : string option + [] + DefaultDeleteBranchAfterMerge : bool option + [] + DefaultMergeStyle : string option + [] + Description : string option + [] + EnablePrune : bool option + [] + ExternalTracker : ExternalTracker option + [] + ExternalWiki : ExternalWiki option + [] + HasIssues : bool option + [] + HasProjects : bool option + [] + HasPullRequests : bool option + [] + HasWiki : bool option + [] + IgnoreWhitespaceConflicts : bool option + [] + InternalTracker : InternalTracker option + [] + MirrorInterval : string option + [] + Name : string option + [] + Private : bool option + [] + Template : bool option + [] + Website : string option + } + +/// IssueFormField represents a form field +[] +type IssueFormField = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Attributes : Type5 option + [] + Id : string option + [] + Type : string option + [] + Validations : Type6 option + } + +/// IssueTemplate represents an issue template for a repository +[] +type IssueTemplate = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + About : string option + [] + Body : IssueFormField list option + [] + Content : string option + [] + FileName : string option + [] + Labels : string list option + [] + Name : string option + [] + Ref : string option + [] + Title : string option + } + +/// Milestone milestone is a collection of issues on one repository +[] +type Milestone = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + ClosedAt : string option + [] + ClosedIssues : int option + [] + CreatedAt : string option + [] + Description : string option + [] + DueOn : string option + [] + Id : int option + [] + OpenIssues : int option + [] + State : string option + [] + Title : string option + [] + UpdatedAt : string option + } + +/// NodeInfoUsage contains usage statistics for this server +[] +type NodeInfoUsage = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + LocalComments : int option + [] + LocalPosts : int option + [] + Users : NodeInfoUsageUsers option + } + +/// NotificationSubject contains the notification subject (Issue/Pull/Commit) +[] +type NotificationSubject = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + HtmlUrl : string option + [] + LatestCommentHtmlUrl : string option + [] + LatestCommentUrl : string option + [] + State : string option + [] + Title : string option + [] + Type : string option + [] + Url : string option + } + +/// PayloadCommitVerification represents the GPG verification of a commit +[] +type PayloadCommitVerification = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Payload : string option + [] + Reason : string option + [] + Signature : string option + [] + Signer : PayloadUser option + [] + Verified : bool option + } + +/// PublicKey publickey is a user key to push code to repository +[] +type PublicKey = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CreatedAt : string option + [] + Fingerprint : string option + [] + Id : int option + [] + Key : string option + [] + KeyType : string option + [] + ReadOnly : bool option + [] + Title : string option + [] + Url : string option + [] + User : User option + } + +/// PullReview represents a pull request review +[] +type PullReview = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + CommentsCount : int option + [] + CommitId : string option + [] + Dismissed : bool option + [] + HtmlUrl : string option + [] + Id : int option + [] + Official : bool option + [] + PullRequestUrl : string option + [] + Stale : bool option + [] + State : string option + [] + SubmittedAt : string option + [] + Team : Team option + [] + UpdatedAt : string option + [] + User : User option + } + +/// PullReviewComment represents a comment on a pull request review +[] +type PullReviewComment = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Body : string option + [] + CommitId : string option + [] + CreatedAt : string option + [] + DiffHunk : string option + [] + HtmlUrl : string option + [] + Id : int option + [] + OriginalCommitId : string option + [] + OriginalPosition : int option + [] + Path : string option + [] + Position : int option + [] + PullRequestReviewId : int option + [] + PullRequestUrl : string option + [] + Resolver : User option + [] + UpdatedAt : string option + [] + User : User option + } + +/// Reaction contain one reaction +[] +type Reaction = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Content : string option + [] + CreatedAt : string option + [] + User : User option + } + +/// Release represents a repository release +[] +type Release = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assets : Attachment list option + [] + Author : User option + [] + Body : string option + [] + CreatedAt : string option + [] + Draft : bool option + [] + HtmlUrl : string option + [] + Id : int option + [] + Name : string option + [] + Prerelease : bool option + [] + PublishedAt : string option + [] + TagName : string option + [] + TarballUrl : string option + [] + TargetCommitish : string option + [] + Url : string option + [] + ZipballUrl : string option + } + +/// RepoCollaboratorPermission to get repository permission for a collaborator +[] +type RepoCollaboratorPermission = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Permission : string option + [] + RoleName : string option + [] + User : User option + } + +/// RepoCommit contains information of a commit in the context of a repository. +[] +type RepoCommit = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : CommitUser option + [] + Committer : CommitUser option + [] + Message : string option + [] + Tree : CommitMeta option + [] + Url : string option + [] + Verification : PayloadCommitVerification option + } + +/// RepoTransfer represents a pending repo transfer +[] +type RepoTransfer = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Doer : User option + [] + Recipient : User option + [] + Teams : Team list option + } + +/// Repository represents a repository +[] +type Repository = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowMergeCommits : bool option + [] + AllowRebase : bool option + [] + AllowRebaseExplicit : bool option + [] + AllowRebaseUpdate : bool option + [] + AllowSquashMerge : bool option + [] + Archived : bool option + [] + AvatarUrl : string option + [] + CloneUrl : string option + [] + CreatedAt : string option + [] + DefaultAllowMaintainerEdit : bool option + [] + DefaultBranch : string option + [] + DefaultDeleteBranchAfterMerge : bool option + [] + DefaultMergeStyle : string option + [] + Description : string option + [] + Empty : bool option + [] + ExternalTracker : ExternalTracker option + [] + ExternalWiki : ExternalWiki option + [] + Fork : bool option + [] + ForksCount : int option + [] + FullName : string option + [] + HasIssues : bool option + [] + HasProjects : bool option + [] + HasPullRequests : bool option + [] + HasWiki : bool option + [] + HtmlUrl : string option + [] + Id : int option + [] + IgnoreWhitespaceConflicts : bool option + [] + Internal : bool option + [] + InternalTracker : InternalTracker option + [] + Language : string option + [] + LanguagesUrl : string option + [] + Link : string option + [] + Mirror : bool option + [] + MirrorInterval : string option + [] + MirrorUpdated : string option + [] + Name : string option + [] + OpenIssuesCount : int option + [] + OpenPrCounter : int option + [] + OriginalUrl : string option + [] + Owner : User option + [] + Parent : Repository option + [] + Permissions : Permission option + [] + Private : bool option + [] + ReleaseCounter : int option + [] + RepoTransfer : RepoTransfer option + [] + Size : int option + [] + SshUrl : string option + [] + StarsCount : int option + [] + Template : bool option + [] + UpdatedAt : string option + [] + WatchersCount : int option + [] + Website : string option + } + +/// SearchResults results of a successful search +[] +type SearchResults = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Data : Repository list option + [] + Ok : bool option + } + +/// AnnotatedTag represents an annotated tag +[] +type AnnotatedTag = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Message : string option + [] + Object : AnnotatedTagObject option + [] + Sha : string option + [] + Tag : string option + [] + Tagger : CommitUser option + [] + Url : string option + [] + Verification : PayloadCommitVerification option + } + +/// CombinedStatus holds the combined state of several statuses for a single commit +[] +type CombinedStatus = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CommitUrl : string option + [] + Repository : Repository option + [] + Sha : string option + [] + State : string option + [] + Statuses : CommitStatus list option + [] + TotalCount : int option + [] + Url : string option + } + +/// Commit contains information generated from a Git commit. +[] +type Commit = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Author : User option + [] + Commit : RepoCommit option + [] + Committer : User option + [] + Created : string option + [] + Files : CommitAffectedFiles list option + [] + HtmlUrl : string option + [] + Parents : CommitMeta list option + [] + Sha : string option + [] + Stats : CommitStats option + [] + Url : string option + } + +/// DeployKey a deploy key +[] +type DeployKey = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CreatedAt : string option + [] + Fingerprint : string option + [] + Id : int option + [] + Key : string option + [] + KeyId : int option + [] + ReadOnly : bool option + [] + Repository : Repository option + [] + Title : string option + [] + Url : string option + } + +/// FileDeleteResponse contains information about a repo's file that was deleted +[] +type FileDeleteResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commit : FileCommitResponse option + [] + Content : unit option + [] + Verification : PayloadCommitVerification option + } + +/// FileResponse contains information about a repo's file +[] +type FileResponse = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commit : FileCommitResponse option + [] + Content : ContentsResponse option + [] + Verification : PayloadCommitVerification option + } + +/// Issue represents an issue in a repository +[] +type Issue = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assets : Attachment list option + [] + Assignee : User option + [] + Assignees : User list option + [] + Body : string option + [] + ClosedAt : string option + [] + Comments : int option + [] + CreatedAt : string option + [] + DueDate : string option + [] + HtmlUrl : string option + [] + Id : int option + [] + IsLocked : bool option + [] + Labels : Label list option + [] + Milestone : Milestone option + [] + Number : int option + [] + OriginalAuthor : string option + [] + OriginalAuthorId : int option + [] + PullRequest : PullRequestMeta option + [] + Ref : string option + [] + Repository : RepositoryMeta option + [] + State : string option + [] + Title : string option + [] + UpdatedAt : string option + [] + Url : string option + [] + User : User option + } + +/// NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks +[] +type NodeInfo = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Metadata : Type7 option + [] + OpenRegistrations : bool option + [] + Protocols : string list option + [] + Services : NodeInfoServices option + [] + Software : NodeInfoSoftware option + [] + Usage : NodeInfoUsage option + [] + Version : string option + } + +/// Note contains information related to a git note +[] +type Note = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commit : Commit option + [] + Message : string option + } + +/// NotificationThread expose Notification on API +[] +type NotificationThread = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Id : int option + [] + Pinned : bool option + [] + Repository : Repository option + [] + Subject : NotificationSubject option + [] + Unread : bool option + [] + UpdatedAt : string option + [] + Url : string option + } + +/// PRBranchInfo information about a branch +[] +type PRBranchInfo = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Label : string option + [] + Ref : string option + [] + Repo : Repository option + [] + RepoId : int option + [] + Sha : string option + } + +/// Package represents a package +[] +type Package = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + CreatedAt : string option + [] + Creator : User option + [] + Id : int option + [] + Name : string option + [] + Owner : User option + [] + Repository : Repository option + [] + Type : string option + [] + Version : string option + } + +/// PayloadCommit represents a commit +[] +type PayloadCommit = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Added : string list option + [] + Author : PayloadUser option + [] + Committer : PayloadUser option + [] + Id : string option + [] + Message : string option + [] + Modified : string list option + [] + Removed : string list option + [] + Timestamp : string option + [] + Url : string option + [] + Verification : PayloadCommitVerification option + } + +/// PullRequest represents a pull request +[] +type PullRequest = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + AllowMaintainerEdit : bool option + [] + Assignee : User option + [] + Assignees : User list option + [] + Base : PRBranchInfo option + [] + Body : string option + [] + ClosedAt : string option + [] + Comments : int option + [] + CreatedAt : string option + [] + DiffUrl : string option + [] + DueDate : string option + [] + Head : PRBranchInfo option + [] + HtmlUrl : string option + [] + Id : int option + [] + IsLocked : bool option + [] + Labels : Label list option + [] + MergeBase : string option + [] + MergeCommitSha : string option + [] + Mergeable : bool option + [] + Merged : bool option + [] + MergedAt : string option + [] + MergedBy : User option + [] + Milestone : Milestone option + [] + Number : int option + [] + PatchUrl : string option + [] + State : string option + [] + Title : string option + [] + UpdatedAt : string option + [] + Url : string option + [] + User : User option + } + +/// TrackedTime worked time for an issue / pr +[] +type TrackedTime = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Created : string option + [] + Id : int option + [] + Issue : Issue option + [] + IssueId : int option + [] + Time : int option + [] + UserId : int option + [] + UserName : string option + } + +/// Branch represents a repository branch +[] +type Branch = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Commit : PayloadCommit option + [] + EffectiveBranchProtectionName : string option + [] + EnableStatusCheck : bool option + [] + Name : string option + [] + Protected : bool option + [] + RequiredApprovals : int option + [] + StatusCheckContexts : string list option + [] + UserCanMerge : bool option + [] + UserCanPush : bool option + } + +/// TimelineComment represents a timeline comment (comment of any type) on a commit or issue +[] +type TimelineComment = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + [] + Assignee : User option + [] + AssigneeTeam : Team option + [] + Body : string option + [] + CreatedAt : string option + [] + DependentIssue : Issue option + [] + HtmlUrl : string option + [] + Id : int option + [] + IssueUrl : string option + [] + Label : Label option + [] + Milestone : Milestone option + [] + NewRef : string option + [] + NewTitle : string option + [] + OldMilestone : Milestone option + [] + OldProjectId : int option + [] + OldRef : string option + [] + OldTitle : string option + [] + ProjectId : int option + [] + PullRequestUrl : string option + [] + RefAction : string option + [] + RefComment : Comment option + [] + RefCommitSha : string option + [] + RefIssue : Issue option + [] + RemovedAssignee : bool option + [] + ResolveDoer : User option + [] + ReviewId : int option + [] + TrackedTime : TrackedTime option + [] + Type : string option + [] + UpdatedAt : string option + [] + User : User option + } + +[] +type LanguageStatistics = + { + [] + AdditionalProperties : System.Collections.Generic.Dictionary + } + +/// This documentation describes the Gitea API. +[] +type IGiteaClient = + /// Returns the Person actor for a user + [] + [] + abstract ActivitypubPerson : + [] username : string * ?ct : System.Threading.CancellationToken -> + ActivityPub System.Threading.Tasks.Task + + /// Send to the inbox + [] + [] + abstract ActivitypubPersonInbox : + [] username : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List cron tasks + [] + [] + abstract AdminCronList : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Cron list System.Threading.Tasks.Task + + /// Run cron task + [] + [] + abstract AdminCronRun : + [] task : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List system's webhooks + [] + [] + abstract AdminListHooks : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Hook list System.Threading.Tasks.Task + + /// Create a hook + [] + [] + abstract AdminCreateHook : + [] body : CreateHookOption * ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// Get a hook + [] + [] + abstract AdminGetHook : + [] id : int * ?ct : System.Threading.CancellationToken -> Hook System.Threading.Tasks.Task + + /// Update a hook + [] + [] + abstract AdminEditHook : + [] id : int * + [] body : EditHookOption * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// List all organizations + [] + [] + abstract AdminGetAllOrgs : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Organization list System.Threading.Tasks.Task + + /// List unadopted repositories + [] + [] + abstract AdminUnadoptedList : + [] page : int * + [] limit : int * + [] pattern : string * + ?ct : System.Threading.CancellationToken -> + string list System.Threading.Tasks.Task + + /// Adopt unadopted files as a repository + [] + [] + abstract AdminAdoptRepository : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Delete unadopted files + [] + [] + abstract AdminDeleteUnadoptedRepository : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List all users + [] + [] + abstract AdminGetAllUsers : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Create a user + [] + [] + abstract AdminCreateUser : + [] body : CreateUserOption * ?ct : System.Threading.CancellationToken -> + User System.Threading.Tasks.Task + + /// Delete a user + [] + [] + abstract AdminDeleteUser : + [] username : string * + [] purge : bool * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit an existing user + [] + [] + abstract AdminEditUser : + [] username : string * + [] body : EditUserOption * + ?ct : System.Threading.CancellationToken -> + User System.Threading.Tasks.Task + + /// Add a public key on behalf of a user + [] + [] + abstract AdminCreatePublicKey : + [] username : string * + [] key : CreateKeyOption * + ?ct : System.Threading.CancellationToken -> + PublicKey System.Threading.Tasks.Task + + /// Delete a user's public key + [] + [] + abstract AdminDeleteUserPublicKey : + [] username : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Create an organization + [] + [] + abstract AdminCreateOrg : + [] username : string * + [] organization : CreateOrgOption * + ?ct : System.Threading.CancellationToken -> + Organization System.Threading.Tasks.Task + + /// Create a repository on behalf of a user + [] + [] + abstract AdminCreateRepo : + [] username : string * + [] repository : CreateRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Delete a hook + [] + [] + abstract AdminDeleteHook : + [] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// Render a markdown document as HTML + [] + [] + abstract RenderMarkdown : + [] body : MarkdownOption * ?ct : System.Threading.CancellationToken -> + string System.Threading.Tasks.Task + + /// Render raw markdown as HTML + [] + [] + abstract RenderMarkdownRaw : + [] body : string * ?ct : System.Threading.CancellationToken -> string System.Threading.Tasks.Task + + /// Returns the nodeinfo of the Gitea application + [] + [] + abstract GetNodeInfo : ?ct : System.Threading.CancellationToken -> NodeInfo System.Threading.Tasks.Task + + /// List users's notification threads + [] + [] + abstract NotifyGetList : + [] all : bool * + [] status_types : string list * + [] subject_type : string list * + [] since : string * + [] before : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + NotificationThread list System.Threading.Tasks.Task + + /// Mark notification threads as read, pinned or unread + [] + [] + abstract NotifyReadList : + [] last_read_at : string * + [] all : string * + [] status_types : string list * + [] to_status : string * + ?ct : System.Threading.CancellationToken -> + NotificationThread list System.Threading.Tasks.Task + + /// Check if unread notifications exist + [] + [] + abstract NotifyNewAvailable : + ?ct : System.Threading.CancellationToken -> NotificationCount System.Threading.Tasks.Task + + /// Get notification thread by ID + [] + [] + abstract NotifyGetThread : + [] id : string * ?ct : System.Threading.CancellationToken -> + NotificationThread System.Threading.Tasks.Task + + /// Mark notification thread as read by ID + [] + [] + abstract NotifyReadThread : + [] id : string * + [] to_status : string * + ?ct : System.Threading.CancellationToken -> + NotificationThread System.Threading.Tasks.Task + + /// Create a repository in an organization + [] + [] + abstract CreateOrgRepoDeprecated : + [] org : string * + [] body : CreateRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Get list of organizations + [] + [] + abstract OrgGetAll : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Organization list System.Threading.Tasks.Task + + /// Create an organization + [] + [] + abstract OrgCreate : + [] organization : CreateOrgOption * ?ct : System.Threading.CancellationToken -> + Organization System.Threading.Tasks.Task + + /// Get an organization + [] + [] + abstract OrgGet : + [] org : string * ?ct : System.Threading.CancellationToken -> + Organization System.Threading.Tasks.Task + + /// Delete an organization + [] + [] + abstract OrgDelete : + [] org : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit an organization + [] + [] + abstract OrgEdit : + [] org : string * + [] body : EditOrgOption * + ?ct : System.Threading.CancellationToken -> + Organization System.Threading.Tasks.Task + + /// List an organization's webhooks + [] + [] + abstract OrgListHooks : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Hook list System.Threading.Tasks.Task + + /// Create a hook + [] + [] + abstract OrgCreateHook : + [] org : string * + [] body : CreateHookOption * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// Get a hook + [] + [] + abstract OrgGetHook : + [] org : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// Delete a hook + [] + [] + abstract OrgDeleteHook : + [] org : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Update a hook + [] + [] + abstract OrgEditHook : + [] org : string * + [] id : int * + [] body : EditHookOption * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// List an organization's labels + [] + [] + abstract OrgListLabels : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Label list System.Threading.Tasks.Task + + /// Create a label for an organization + [] + [] + abstract OrgCreateLabel : + [] org : string * + [] body : CreateLabelOption * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// Get a single label + [] + [] + abstract OrgGetLabel : + [] org : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// Delete a label + [] + [] + abstract OrgDeleteLabel : + [] org : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Update a label + [] + [] + abstract OrgEditLabel : + [] org : string * + [] id : int * + [] body : EditLabelOption * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// List an organization's members + [] + [] + abstract OrgListMembers : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if a user is a member of an organization + [] + [] + abstract OrgIsMember : + [] org : string * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Remove a member from an organization + [] + [] + abstract OrgDeleteMember : + [] org : string * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List an organization's public members + [] + [] + abstract OrgListPublicMembers : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if a user is a public member of an organization + [] + [] + abstract OrgIsPublicMember : + [] org : string * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Conceal a user's membership + [] + [] + abstract OrgConcealMember : + [] org : string * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Publicize a user's membership + [] + [] + abstract OrgPublicizeMember : + [] org : string * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List an organization's repos + [] + [] + abstract OrgListRepos : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// Create a repository in an organization + [] + [] + abstract CreateOrgRepo : + [] org : string * + [] body : CreateRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// List an organization's teams + [] + [] + abstract OrgListTeams : + [] org : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Team list System.Threading.Tasks.Task + + /// Create a team + [] + [] + abstract OrgCreateTeam : + [] org : string * + [] body : CreateTeamOption * + ?ct : System.Threading.CancellationToken -> + Team System.Threading.Tasks.Task + + /// Search for teams within an organization + [] + [] + abstract TeamSearch : + [] org : string * + [] q : string * + [] include_desc : bool * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Gets all packages of an owner + [] + [] + abstract ListPackages : + [] owner : string * + [] page : int * + [] limit : int * + [] type' : string * + [] q : string * + ?ct : System.Threading.CancellationToken -> + Package list System.Threading.Tasks.Task + + /// Gets a package + [] + [] + abstract GetPackage : + [] owner : string * + [] type' : string * + [] name : string * + [] version : string * + ?ct : System.Threading.CancellationToken -> + Package System.Threading.Tasks.Task + + /// Delete a package + [] + [] + abstract DeletePackage : + [] owner : string * + [] type' : string * + [] name : string * + [] version : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Gets all files of a package + [] + [] + abstract ListPackageFiles : + [] owner : string * + [] type' : string * + [] name : string * + [] version : string * + ?ct : System.Threading.CancellationToken -> + PackageFile list System.Threading.Tasks.Task + + /// Search for issues across the repositories that the user has access to + [] + [] + abstract IssueSearchIssues : + [] state : string * + [] labels : string * + [] milestones : string * + [] q : string * + [] priority_repo_id : int * + [] type' : string * + [] since : string * + [] before : string * + [] assigned : bool * + [] created : bool * + [] mentioned : bool * + [] review_requested : bool * + [] owner : string * + [] team : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Issue list System.Threading.Tasks.Task + + /// Migrate a remote git repository + [] + [] + abstract RepoMigrate : + [] body : MigrateRepoOptions * ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Search for repositories + [] + [] + abstract RepoSearch : + [] q : string * + [] topic : bool * + [] includeDesc : bool * + [] uid : int * + [] priority_owner_id : int * + [] team_id : int * + [] starredBy : int * + [] private' : bool * + [] is_private : bool * + [] template : bool * + [] archived : bool * + [] mode : string * + [] exclusive : bool * + [] sort : string * + [] order : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + SearchResults System.Threading.Tasks.Task + + /// Get a repository + [] + [] + abstract RepoGet : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Delete a repository + [] + [] + abstract RepoDelete : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a repository's properties. Only fields that are set will be changed. + [] + [] + abstract RepoEdit : + [] owner : string * + [] repo : string * + [] body : EditRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Get an archive of a repository + [] + [] + abstract RepoGetArchive : + [] owner : string * + [] repo : string * + [] archive : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Return all users that have write access and can be assigned to issues + [] + [] + abstract RepoGetAssignees : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// List branch protections for a repository + [] + [] + abstract RepoListBranchProtection : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + BranchProtection list System.Threading.Tasks.Task + + /// Create a branch protections for a repository + [] + [] + abstract RepoCreateBranchProtection : + [] owner : string * + [] repo : string * + [] body : CreateBranchProtectionOption * + ?ct : System.Threading.CancellationToken -> + BranchProtection System.Threading.Tasks.Task + + /// Get a specific branch protection for the repository + [] + [] + abstract RepoGetBranchProtection : + [] owner : string * + [] repo : string * + [] name : string * + ?ct : System.Threading.CancellationToken -> + BranchProtection System.Threading.Tasks.Task + + /// Delete a specific branch protection for the repository + [] + [] + abstract RepoDeleteBranchProtection : + [] owner : string * + [] repo : string * + [] name : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a branch protections for a repository. Only fields that are set will be changed + [] + [] + abstract RepoEditBranchProtection : + [] owner : string * + [] repo : string * + [] name : string * + [] body : EditBranchProtectionOption * + ?ct : System.Threading.CancellationToken -> + BranchProtection System.Threading.Tasks.Task + + /// List a repository's branches + [] + [] + abstract RepoListBranches : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Branch list System.Threading.Tasks.Task + + /// Create a branch + [] + [] + abstract RepoCreateBranch : + [] owner : string * + [] repo : string * + [] body : CreateBranchRepoOption * + ?ct : System.Threading.CancellationToken -> + Branch System.Threading.Tasks.Task + + /// Retrieve a specific branch from a repository, including its effective branch protection + [] + [] + abstract RepoGetBranch : + [] owner : string * + [] repo : string * + [] branch : string * + ?ct : System.Threading.CancellationToken -> + Branch System.Threading.Tasks.Task + + /// Delete a specific branch from a repository + [] + [] + abstract RepoDeleteBranch : + [] owner : string * + [] repo : string * + [] branch : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repository's collaborators + [] + [] + abstract RepoListCollaborators : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if a user is a collaborator of a repository + [] + [] + abstract RepoCheckCollaborator : + [] owner : string * + [] repo : string * + [] collaborator : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Delete a collaborator from a repository + [] + [] + abstract RepoDeleteCollaborator : + [] owner : string * + [] repo : string * + [] collaborator : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Add a collaborator to a repository + [] + [] + abstract RepoAddCollaborator : + [] owner : string * + [] repo : string * + [] collaborator : string * + [] body : AddCollaboratorOption * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get repository permissions for a user + [] + [] + abstract RepoGetRepoPermissions : + [] owner : string * + [] repo : string * + [] collaborator : string * + ?ct : System.Threading.CancellationToken -> + RepoCollaboratorPermission System.Threading.Tasks.Task + + /// Get a list of all commits from a repository + [] + [] + abstract RepoGetAllCommits : + [] owner : string * + [] repo : string * + [] sha : string * + [] path : string * + [] stat : bool * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Commit list System.Threading.Tasks.Task + + /// Get a commit's combined status, by branch/tag/commit reference + [] + [] + abstract RepoGetCombinedStatusByRef : + [] owner : string * + [] repo : string * + [] ref : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + CombinedStatus System.Threading.Tasks.Task + + /// Get a commit's statuses, by branch/tag/commit reference + [] + [] + abstract RepoListStatusesByRef : + [] owner : string * + [] repo : string * + [] ref : string * + [] sort : string * + [] state : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + CommitStatus list System.Threading.Tasks.Task + + /// Gets the metadata of all the entries of the root dir + [] + [] + abstract RepoGetContentsList : + [] owner : string * + [] repo : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + ContentsResponse list System.Threading.Tasks.Task + + /// Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir + [] + [] + abstract RepoGetContents : + [] owner : string * + [] repo : string * + [] filepath : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + ContentsResponse System.Threading.Tasks.Task + + /// Create a file in a repository + [] + [] + abstract RepoCreateFile : + [] owner : string * + [] repo : string * + [] filepath : string * + [] body : CreateFileOptions * + ?ct : System.Threading.CancellationToken -> + FileResponse System.Threading.Tasks.Task + + /// Delete a file in a repository + [] + [] + abstract RepoDeleteFile : + [] owner : string * + [] repo : string * + [] filepath : string * + [] body : DeleteFileOptions * + ?ct : System.Threading.CancellationToken -> + FileDeleteResponse System.Threading.Tasks.Task + + /// Update a file in a repository + [] + [] + abstract RepoUpdateFile : + [] owner : string * + [] repo : string * + [] filepath : string * + [] body : UpdateFileOptions * + ?ct : System.Threading.CancellationToken -> + FileResponse System.Threading.Tasks.Task + + /// Apply diff patch to repository + [] + [] + abstract RepoApplyDiffPatch : + [] owner : string * + [] repo : string * + [] body : UpdateFileOptions * + ?ct : System.Threading.CancellationToken -> + FileResponse System.Threading.Tasks.Task + + /// Get the EditorConfig definitions of a file in a repository + [] + [] + abstract RepoGetEditorConfig : + [] owner : string * + [] repo : string * + [] filepath : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repository's forks + [] + [] + abstract ListForks : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// Fork a repository + [] + [] + abstract CreateFork : + [] owner : string * + [] repo : string * + [] body : CreateForkOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Gets the blob of a repository. + [] + [] + abstract GetBlob : + [] owner : string * + [] repo : string * + [] sha : string * + ?ct : System.Threading.CancellationToken -> + GitBlobResponse System.Threading.Tasks.Task + + /// Get a single commit from a repository + [] + [] + abstract RepoGetSingleCommit : + [] owner : string * + [] repo : string * + [] sha : string * + ?ct : System.Threading.CancellationToken -> + Commit System.Threading.Tasks.Task + + /// Get a commit's diff or patch + [] + [] + abstract RepoDownloadCommitDiffOrPatch : + [] owner : string * + [] repo : string * + [] sha : string * + [] diffType : string * + ?ct : System.Threading.CancellationToken -> + string System.Threading.Tasks.Task + + /// Get a note corresponding to a single commit from a repository + [] + [] + abstract RepoGetNote : + [] owner : string * + [] repo : string * + [] sha : string * + ?ct : System.Threading.CancellationToken -> + Note System.Threading.Tasks.Task + + /// Get specified ref or filtered repository's refs + [] + [] + abstract RepoListAllGitRefs : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Reference list System.Threading.Tasks.Task + + /// Get specified ref or filtered repository's refs + [] + [] + abstract RepoListGitRefs : + [] owner : string * + [] repo : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + Reference list System.Threading.Tasks.Task + + /// Gets the tag object of an annotated tag (not lightweight tags) + [] + [] + abstract GetAnnotatedTag : + [] owner : string * + [] repo : string * + [] sha : string * + ?ct : System.Threading.CancellationToken -> + AnnotatedTag System.Threading.Tasks.Task + + /// Gets the tree of a repository. + [] + [] + abstract GetTree : + [] owner : string * + [] repo : string * + [] sha : string * + [] recursive : bool * + [] page : int * + [] per_page : int * + ?ct : System.Threading.CancellationToken -> + GitTreeResponse System.Threading.Tasks.Task + + /// List the hooks in a repository + [] + [] + abstract RepoListHooks : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Hook list System.Threading.Tasks.Task + + /// Create a hook + [] + [] + abstract RepoCreateHook : + [] owner : string * + [] repo : string * + [] body : CreateHookOption * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// List the Git hooks in a repository + [] + [] + abstract RepoListGitHooks : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + GitHook list System.Threading.Tasks.Task + + /// Get a Git hook + [] + [] + abstract RepoGetGitHook : + [] owner : string * + [] repo : string * + [] id : string * + ?ct : System.Threading.CancellationToken -> + GitHook System.Threading.Tasks.Task + + /// Delete a Git hook in a repository + [] + [] + abstract RepoDeleteGitHook : + [] owner : string * + [] repo : string * + [] id : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a Git hook in a repository + [] + [] + abstract RepoEditGitHook : + [] owner : string * + [] repo : string * + [] id : string * + [] body : EditGitHookOption * + ?ct : System.Threading.CancellationToken -> + GitHook System.Threading.Tasks.Task + + /// Get a hook + [] + [] + abstract RepoGetHook : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// Delete a hook in a repository + [] + [] + abstract RepoDeleteHook : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a hook in a repository + [] + [] + abstract RepoEditHook : + [] owner : string * + [] repo : string * + [] id : int * + [] body : EditHookOption * + ?ct : System.Threading.CancellationToken -> + Hook System.Threading.Tasks.Task + + /// Test a push webhook + [] + [] + abstract RepoTestHook : + [] owner : string * + [] repo : string * + [] id : int * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get available issue templates for a repository + [] + [] + abstract RepoGetIssueTemplates : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + IssueTemplate list System.Threading.Tasks.Task + + /// List a repository's issues + [] + [] + abstract IssueListIssues : + [] owner : string * + [] repo : string * + [] state : string * + [] labels : string * + [] q : string * + [] type' : string * + [] milestones : string * + [] since : string * + [] before : string * + [] created_by : string * + [] assigned_by : string * + [] mentioned_by : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Issue list System.Threading.Tasks.Task + + /// Create an issue. If using deadline only the date will be taken into account, and time of day ignored. + [] + [] + abstract IssueCreateIssue : + [] owner : string * + [] repo : string * + [] body : CreateIssueOption * + ?ct : System.Threading.CancellationToken -> + Issue System.Threading.Tasks.Task + + /// List all comments in a repository + [] + [] + abstract IssueGetRepoComments : + [] owner : string * + [] repo : string * + [] since : string * + [] before : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Comment list System.Threading.Tasks.Task + + /// Delete a comment + [] + [] + abstract IssueDeleteComment : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List comment's attachments + [] + [] + abstract IssueListIssueCommentAttachments : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Attachment list System.Threading.Tasks.Task + + /// Get a comment attachment + [] + [] + abstract IssueGetIssueCommentAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// Delete a comment attachment + [] + [] + abstract IssueDeleteIssueCommentAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a comment attachment + [] + [] + abstract IssueEditIssueCommentAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + [] body : EditAttachmentOptions * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// Get a list of reactions from a comment of an issue + [] + [] + abstract IssueGetCommentReactions : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Reaction list System.Threading.Tasks.Task + + /// Remove a reaction from a comment of an issue + [] + [] + abstract IssueDeleteCommentReaction : + [] owner : string * + [] repo : string * + [] id : int * + [] content : EditReactionOption * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get an issue + [] + [] + abstract IssueGetIssue : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + Issue System.Threading.Tasks.Task + + /// Delete an issue + [] + [] + abstract IssueDelete : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit an issue. If using deadline only the date will be taken into account, and time of day ignored. + [] + [] + abstract IssueEditIssue : + [] owner : string * + [] repo : string * + [] index : int * + [] body : EditIssueOption * + ?ct : System.Threading.CancellationToken -> + Issue System.Threading.Tasks.Task + + /// List issue's attachments + [] + [] + abstract IssueListIssueAttachments : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + Attachment list System.Threading.Tasks.Task + + /// Get an issue attachment + [] + [] + abstract IssueGetIssueAttachment : + [] owner : string * + [] repo : string * + [] index : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// Delete an issue attachment + [] + [] + abstract IssueDeleteIssueAttachment : + [] owner : string * + [] repo : string * + [] index : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit an issue attachment + [] + [] + abstract IssueEditIssueAttachment : + [] owner : string * + [] repo : string * + [] index : int * + [] attachment_id : int * + [] body : EditAttachmentOptions * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// List all comments on an issue + [] + [] + abstract IssueGetComments : + [] owner : string * + [] repo : string * + [] index : int * + [] since : string * + [] before : string * + ?ct : System.Threading.CancellationToken -> + Comment list System.Threading.Tasks.Task + + /// Add a comment to an issue + [] + [] + abstract IssueCreateComment : + [] owner : string * + [] repo : string * + [] index : int * + [] body : CreateIssueCommentOption * + ?ct : System.Threading.CancellationToken -> + Comment System.Threading.Tasks.Task + + /// Delete a comment + [] + [] + abstract IssueDeleteCommentDeprecated : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Set an issue deadline. If set to null, the deadline is deleted. If using deadline only the date will be taken into account, and time of day ignored. + [] + [] + abstract IssueEditIssueDeadline : + [] owner : string * + [] repo : string * + [] index : int * + [] body : EditDeadlineOption * + ?ct : System.Threading.CancellationToken -> + IssueDeadline System.Threading.Tasks.Task + + /// Get an issue's labels + [] + [] + abstract IssueGetLabels : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + Label list System.Threading.Tasks.Task + + /// Add a label to an issue + [] + [] + abstract IssueAddLabel : + [] owner : string * + [] repo : string * + [] index : int * + [] body : IssueLabelsOption * + ?ct : System.Threading.CancellationToken -> + Label list System.Threading.Tasks.Task + + /// Remove all labels from an issue + [] + [] + abstract IssueClearLabels : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Replace an issue's labels + [] + [] + abstract IssueReplaceLabels : + [] owner : string * + [] repo : string * + [] index : int * + [] body : IssueLabelsOption * + ?ct : System.Threading.CancellationToken -> + Label list System.Threading.Tasks.Task + + /// Remove a label from an issue + [] + [] + abstract IssueRemoveLabel : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a list reactions of an issue + [] + [] + abstract IssueGetIssueReactions : + [] owner : string * + [] repo : string * + [] index : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Reaction list System.Threading.Tasks.Task + + /// Remove a reaction from an issue + [] + [] + abstract IssueDeleteIssueReaction : + [] owner : string * + [] repo : string * + [] index : int * + [] content : EditReactionOption * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Delete an issue's existing stopwatch. + [] + [] + abstract IssueDeleteStopWatch : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Start stopwatch on an issue. + [] + [] + abstract IssueStartStopWatch : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Stop an issue's existing stopwatch. + [] + [] + abstract IssueStopStopWatch : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get users who subscribed on an issue. + [] + [] + abstract IssueSubscriptions : + [] owner : string * + [] repo : string * + [] index : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if user is subscribed to an issue + [] + [] + abstract IssueCheckSubscription : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + WatchInfo System.Threading.Tasks.Task + + /// List all comments and events on an issue + [] + [] + abstract IssueGetCommentsAndTimeline : + [] owner : string * + [] repo : string * + [] index : int * + [] since : string * + [] page : int * + [] limit : int * + [] before : string * + ?ct : System.Threading.CancellationToken -> + TimelineComment list System.Threading.Tasks.Task + + /// List an issue's tracked times + [] + [] + abstract IssueTrackedTimes : + [] owner : string * + [] repo : string * + [] index : int * + [] user : string * + [] since : string * + [] before : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + TrackedTime list System.Threading.Tasks.Task + + /// Add tracked time to a issue + [] + [] + abstract IssueAddTime : + [] owner : string * + [] repo : string * + [] index : int * + [] body : AddTimeOption * + ?ct : System.Threading.CancellationToken -> + TrackedTime System.Threading.Tasks.Task + + /// Reset a tracked time of an issue + [] + [] + abstract IssueResetTime : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Delete specific tracked time + [] + [] + abstract IssueDeleteTime : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repository's keys + [] + [] + abstract RepoListKeys : + [] owner : string * + [] repo : string * + [] key_id : int * + [] fingerprint : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + DeployKey list System.Threading.Tasks.Task + + /// Add a key to a repository + [] + [] + abstract RepoCreateKey : + [] owner : string * + [] repo : string * + [] body : CreateKeyOption * + ?ct : System.Threading.CancellationToken -> + DeployKey System.Threading.Tasks.Task + + /// Get a repository's key by id + [] + [] + abstract RepoGetKey : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + DeployKey System.Threading.Tasks.Task + + /// Delete a key from a repository + [] + [] + abstract RepoDeleteKey : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get all of a repository's labels + [] + [] + abstract IssueListLabels : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Label list System.Threading.Tasks.Task + + /// Create a label + [] + [] + abstract IssueCreateLabel : + [] owner : string * + [] repo : string * + [] body : CreateLabelOption * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// Get a single label + [] + [] + abstract IssueGetLabel : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// Delete a label + [] + [] + abstract IssueDeleteLabel : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Update a label + [] + [] + abstract IssueEditLabel : + [] owner : string * + [] repo : string * + [] id : int * + [] body : EditLabelOption * + ?ct : System.Threading.CancellationToken -> + Label System.Threading.Tasks.Task + + /// Get languages and number of bytes of code written + [] + [] + abstract RepoGetLanguages : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + LanguageStatistics System.Threading.Tasks.Task + + /// Get a file or it's LFS object from a repository + [] + [] + abstract RepoGetRawFileOrLFS : + [] owner : string * + [] repo : string * + [] filepath : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get all of a repository's opened milestones + [] + [] + abstract IssueGetMilestonesList : + [] owner : string * + [] repo : string * + [] state : string * + [] name : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Milestone list System.Threading.Tasks.Task + + /// Create a milestone + [] + [] + abstract IssueCreateMilestone : + [] owner : string * + [] repo : string * + [] body : CreateMilestoneOption * + ?ct : System.Threading.CancellationToken -> + Milestone System.Threading.Tasks.Task + + /// Get a milestone + [] + [] + abstract IssueGetMilestone : + [] owner : string * + [] repo : string * + [] id : string * + ?ct : System.Threading.CancellationToken -> + Milestone System.Threading.Tasks.Task + + /// Delete a milestone + [] + [] + abstract IssueDeleteMilestone : + [] owner : string * + [] repo : string * + [] id : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Update a milestone + [] + [] + abstract IssueEditMilestone : + [] owner : string * + [] repo : string * + [] id : string * + [] body : EditMilestoneOption * + ?ct : System.Threading.CancellationToken -> + Milestone System.Threading.Tasks.Task + + /// Sync a mirrored repository + [] + [] + abstract RepoMirrorSync : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List users's notification threads on a specific repo + [] + [] + abstract NotifyGetRepoList : + [] owner : string * + [] repo : string * + [] all : bool * + [] status_types : string list * + [] subject_type : string list * + [] since : string * + [] before : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + NotificationThread list System.Threading.Tasks.Task + + /// Mark notification threads as read, pinned or unread on a specific repo + [] + [] + abstract NotifyReadRepoList : + [] owner : string * + [] repo : string * + [] all : string * + [] status_types : string list * + [] to_status : string * + [] last_read_at : string * + ?ct : System.Threading.CancellationToken -> + NotificationThread list System.Threading.Tasks.Task + + /// List a repo's pull requests + [] + [] + abstract RepoListPullRequests : + [] owner : string * + [] repo : string * + [] state : string * + [] sort : string * + [] milestone : int * + [] labels : int list * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + PullRequest list System.Threading.Tasks.Task + + /// Create a pull request + [] + [] + abstract RepoCreatePullRequest : + [] owner : string * + [] repo : string * + [] body : CreatePullRequestOption * + ?ct : System.Threading.CancellationToken -> + PullRequest System.Threading.Tasks.Task + + /// Get a pull request + [] + [] + abstract RepoGetPullRequest : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + PullRequest System.Threading.Tasks.Task + + /// Update a pull request. If using deadline only the date will be taken into account, and time of day ignored. + [] + [] + abstract RepoEditPullRequest : + [] owner : string * + [] repo : string * + [] index : int * + [] body : EditPullRequestOption * + ?ct : System.Threading.CancellationToken -> + PullRequest System.Threading.Tasks.Task + + /// Get a pull request diff or patch + [] + [] + abstract RepoDownloadPullDiffOrPatch : + [] owner : string * + [] repo : string * + [] index : int * + [] diffType : string * + [] binary : bool * + ?ct : System.Threading.CancellationToken -> + string System.Threading.Tasks.Task + + /// Get commits for a pull request + [] + [] + abstract RepoGetPullRequestCommits : + [] owner : string * + [] repo : string * + [] index : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Commit list System.Threading.Tasks.Task + + /// Get changed files for a pull request + [] + [] + abstract RepoGetPullRequestFiles : + [] owner : string * + [] repo : string * + [] index : int * + [] skip_to : string * + [] whitespace : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + ChangedFile list System.Threading.Tasks.Task + + /// Check if a pull request has been merged + [] + [] + abstract RepoPullRequestIsMerged : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Merge a pull request + [] + [] + abstract RepoMergePullRequest : + [] owner : string * + [] repo : string * + [] index : int * + [] body : MergePullRequestOption * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Cancel the scheduled auto merge for the given pull request + [] + [] + abstract RepoCancelScheduledAutoMerge : + [] owner : string * + [] repo : string * + [] index : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// create review requests for a pull request + [] + [] + abstract RepoCreatePullReviewRequests : + [] owner : string * + [] repo : string * + [] index : int * + [] body : PullReviewRequestOptions * + ?ct : System.Threading.CancellationToken -> + PullReview list System.Threading.Tasks.Task + + /// cancel review requests for a pull request + [] + [] + abstract RepoDeletePullReviewRequests : + [] owner : string * + [] repo : string * + [] index : int * + [] body : PullReviewRequestOptions * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List all reviews for a pull request + [] + [] + abstract RepoListPullReviews : + [] owner : string * + [] repo : string * + [] index : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + PullReview list System.Threading.Tasks.Task + + /// Create a review to an pull request + [] + [] + abstract RepoCreatePullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] body : CreatePullReviewOptions * + ?ct : System.Threading.CancellationToken -> + PullReview System.Threading.Tasks.Task + + /// Get a specific review for a pull request + [] + [] + abstract RepoGetPullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + PullReview System.Threading.Tasks.Task + + /// Submit a pending review to an pull request + [] + [] + abstract RepoSubmitPullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + [] body : SubmitPullReviewOptions * + ?ct : System.Threading.CancellationToken -> + PullReview System.Threading.Tasks.Task + + /// Delete a specific review from a pull request + [] + [] + abstract RepoDeletePullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a specific review for a pull request + [] + [] + abstract RepoGetPullReviewComments : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + PullReviewComment list System.Threading.Tasks.Task + + /// Dismiss a review for a pull request + [] + [] + abstract RepoDismissPullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + [] body : DismissPullReviewOptions * + ?ct : System.Threading.CancellationToken -> + PullReview System.Threading.Tasks.Task + + /// Cancel to dismiss a review for a pull request + [] + [] + abstract RepoUnDismissPullReview : + [] owner : string * + [] repo : string * + [] index : int * + [] id : int * + ?ct : System.Threading.CancellationToken -> + PullReview System.Threading.Tasks.Task + + /// Merge PR's baseBranch into headBranch + [] + [] + abstract RepoUpdatePullRequest : + [] owner : string * + [] repo : string * + [] index : int * + [] style : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get all push mirrors of the repository + [] + [] + abstract RepoListPushMirrors : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + PushMirror list System.Threading.Tasks.Task + + /// add a push mirror to the repository + [] + [] + abstract RepoAddPushMirror : + [] owner : string * + [] repo : string * + [] body : CreatePushMirrorOption * + ?ct : System.Threading.CancellationToken -> + PushMirror System.Threading.Tasks.Task + + /// Sync all push mirrored repository + [] + [] + abstract RepoPushMirrorSync : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get push mirror of the repository by remoteName + [] + [] + abstract RepoGetPushMirrorByRemoteName : + [] owner : string * + [] repo : string * + [] name : string * + ?ct : System.Threading.CancellationToken -> + PushMirror System.Threading.Tasks.Task + + /// deletes a push mirror from a repository by remoteName + [] + [] + abstract RepoDeletePushMirror : + [] owner : string * + [] repo : string * + [] name : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a file from a repository + [] + [] + abstract RepoGetRawFile : + [] owner : string * + [] repo : string * + [] filepath : string * + [] ref : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repo's releases + [] + [] + abstract RepoListReleases : + [] owner : string * + [] repo : string * + [] draft : bool * + [] pre_release : bool * + [] per_page : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Release list System.Threading.Tasks.Task + + /// Create a release + [] + [] + abstract RepoCreateRelease : + [] owner : string * + [] repo : string * + [] body : CreateReleaseOption * + ?ct : System.Threading.CancellationToken -> + Release System.Threading.Tasks.Task + + /// Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at + [] + [] + abstract RepoGetLatestRelease : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Release System.Threading.Tasks.Task + + /// Get a release by tag name + [] + [] + abstract RepoGetReleaseByTag : + [] owner : string * + [] repo : string * + [] tag : string * + ?ct : System.Threading.CancellationToken -> + Release System.Threading.Tasks.Task + + /// Delete a release by tag name + [] + [] + abstract RepoDeleteReleaseByTag : + [] owner : string * + [] repo : string * + [] tag : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a release + [] + [] + abstract RepoGetRelease : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Release System.Threading.Tasks.Task + + /// Delete a release + [] + [] + abstract RepoDeleteRelease : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Update a release + [] + [] + abstract RepoEditRelease : + [] owner : string * + [] repo : string * + [] id : int * + [] body : EditReleaseOption * + ?ct : System.Threading.CancellationToken -> + Release System.Threading.Tasks.Task + + /// List release's attachments + [] + [] + abstract RepoListReleaseAttachments : + [] owner : string * + [] repo : string * + [] id : int * + ?ct : System.Threading.CancellationToken -> + Attachment list System.Threading.Tasks.Task + + /// Get a release attachment + [] + [] + abstract RepoGetReleaseAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// Delete a release attachment + [] + [] + abstract RepoDeleteReleaseAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a release attachment + [] + [] + abstract RepoEditReleaseAttachment : + [] owner : string * + [] repo : string * + [] id : int * + [] attachment_id : int * + [] body : EditAttachmentOptions * + ?ct : System.Threading.CancellationToken -> + Attachment System.Threading.Tasks.Task + + /// Return all users that can be requested to review in this repo + [] + [] + abstract RepoGetReviewers : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Get signing-key.gpg for given repository + [] + [] + abstract RepoSigningKey : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repo's stargazers + [] + [] + abstract RepoListStargazers : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Get a commit's statuses + [] + [] + abstract RepoListStatuses : + [] owner : string * + [] repo : string * + [] sha : string * + [] sort : string * + [] state : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + CommitStatus list System.Threading.Tasks.Task + + /// Create a commit status + [] + [] + abstract RepoCreateStatus : + [] owner : string * + [] repo : string * + [] sha : string * + [] body : CreateStatusOption * + ?ct : System.Threading.CancellationToken -> + CommitStatus System.Threading.Tasks.Task + + /// List a repo's watchers + [] + [] + abstract RepoListSubscribers : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if the current user is watching a repo + [] + [] + abstract UserCurrentCheckSubscription : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + WatchInfo System.Threading.Tasks.Task + + /// Unwatch a repo + [] + [] + abstract UserCurrentDeleteSubscription : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Watch a repo + [] + [] + abstract UserCurrentPutSubscription : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + WatchInfo System.Threading.Tasks.Task + + /// List a repository's tags + [] + [] + abstract RepoListTags : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Tag list System.Threading.Tasks.Task + + /// Create a new git tag in a repository + [] + [] + abstract RepoCreateTag : + [] owner : string * + [] repo : string * + [] body : CreateTagOption * + ?ct : System.Threading.CancellationToken -> + Tag System.Threading.Tasks.Task + + /// Get the tag of a repository by tag name + [] + [] + abstract RepoGetTag : + [] owner : string * + [] repo : string * + [] tag : string * + ?ct : System.Threading.CancellationToken -> + Tag System.Threading.Tasks.Task + + /// Delete a repository's tag by name + [] + [] + abstract RepoDeleteTag : + [] owner : string * + [] repo : string * + [] tag : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repository's teams + [] + [] + abstract RepoListTeams : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Team list System.Threading.Tasks.Task + + /// Check if a team is assigned to a repository + [] + [] + abstract RepoCheckTeam : + [] owner : string * + [] repo : string * + [] team : string * + ?ct : System.Threading.CancellationToken -> + Team System.Threading.Tasks.Task + + /// Delete a team from a repository + [] + [] + abstract RepoDeleteTeam : + [] owner : string * + [] repo : string * + [] team : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Add a team to a repository + [] + [] + abstract RepoAddTeam : + [] owner : string * + [] repo : string * + [] team : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a repo's tracked times + [] + [] + abstract RepoTrackedTimes : + [] owner : string * + [] repo : string * + [] user : string * + [] since : string * + [] before : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + TrackedTime list System.Threading.Tasks.Task + + /// List a user's tracked times in a repo + [] + [] + abstract UserTrackedTimes : + [] owner : string * + [] repo : string * + [] user : string * + ?ct : System.Threading.CancellationToken -> + TrackedTime list System.Threading.Tasks.Task + + /// Get list of topics that a repository has + [] + [] + abstract RepoListTopics : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + TopicName System.Threading.Tasks.Task + + /// Replace list of topics for a repository + [] + [] + abstract RepoUpdateTopics : + [] owner : string * + [] repo : string * + [] body : RepoTopicOptions * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Delete a topic from a repository + [] + [] + abstract RepoDeleteTopic : + [] owner : string * + [] repo : string * + [] topic : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Add a topic to a repository + [] + [] + abstract RepoAddTopic : + [] owner : string * + [] repo : string * + [] topic : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Transfer a repo ownership + [] + [] + abstract RepoTransfer : + [] owner : string * + [] repo : string * + [] body : TransferRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Accept a repo transfer + [] + [] + abstract AcceptRepoTransfer : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Reject a repo transfer + [] + [] + abstract RejectRepoTransfer : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Create a wiki page + [] + [] + abstract RepoCreateWikiPage : + [] owner : string * + [] repo : string * + [] body : CreateWikiPageOptions * + ?ct : System.Threading.CancellationToken -> + WikiPage System.Threading.Tasks.Task + + /// Get a wiki page + [] + [] + abstract RepoGetWikiPage : + [] owner : string * + [] repo : string * + [] pageName : string * + ?ct : System.Threading.CancellationToken -> + WikiPage System.Threading.Tasks.Task + + /// Delete a wiki page + [] + [] + abstract RepoDeleteWikiPage : + [] owner : string * + [] repo : string * + [] pageName : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Edit a wiki page + [] + [] + abstract RepoEditWikiPage : + [] owner : string * + [] repo : string * + [] pageName : string * + [] body : CreateWikiPageOptions * + ?ct : System.Threading.CancellationToken -> + WikiPage System.Threading.Tasks.Task + + /// Get all wiki pages + [] + [] + abstract RepoGetWikiPages : + [] owner : string * + [] repo : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + WikiPageMetaData list System.Threading.Tasks.Task + + /// Get revisions of a wiki page + [] + [] + abstract RepoGetWikiPageRevisions : + [] owner : string * + [] repo : string * + [] pageName : string * + [] page : int * + ?ct : System.Threading.CancellationToken -> + WikiCommitList System.Threading.Tasks.Task + + /// Create a repository using a template + [] + [] + abstract GenerateRepo : + [] template_owner : string * + [] template_repo : string * + [] body : GenerateRepoOption * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Get a repository by id + [] + [] + abstract RepoGetByID : + [] id : int * ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Get instance's global settings for api + [] + [] + abstract GetGeneralAPISettings : + ?ct : System.Threading.CancellationToken -> GeneralAPISettings System.Threading.Tasks.Task + + /// Get instance's global settings for Attachment + [] + [] + abstract GetGeneralAttachmentSettings : + ?ct : System.Threading.CancellationToken -> GeneralAttachmentSettings System.Threading.Tasks.Task + + /// Get instance's global settings for repositories + [] + [] + abstract GetGeneralRepositorySettings : + ?ct : System.Threading.CancellationToken -> GeneralRepoSettings System.Threading.Tasks.Task + + /// Get instance's global settings for ui + [] + [] + abstract GetGeneralUISettings : + ?ct : System.Threading.CancellationToken -> GeneralUISettings System.Threading.Tasks.Task + + /// Get default signing-key.gpg + [] + [] + abstract GetSigningKey : ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// Get a team + [] + [] + abstract OrgGetTeam : + [] id : int * ?ct : System.Threading.CancellationToken -> Team System.Threading.Tasks.Task + + /// Delete a team + [] + [] + abstract OrgDeleteTeam : + [] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// Edit a team + [] + [] + abstract OrgEditTeam : + [] id : int * + [] body : EditTeamOption * + ?ct : System.Threading.CancellationToken -> + Team System.Threading.Tasks.Task + + /// List a team's members + [] + [] + abstract OrgListTeamMembers : + [] id : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// List a particular member of team + [] + [] + abstract OrgListTeamMember : + [] id : int * + [] username : string * + ?ct : System.Threading.CancellationToken -> + User System.Threading.Tasks.Task + + /// Remove a team member + [] + [] + abstract OrgRemoveTeamMember : + [] id : int * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Add a team member + [] + [] + abstract OrgAddTeamMember : + [] id : int * + [] username : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List a team's repos + [] + [] + abstract OrgListTeamRepos : + [] id : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// List a particular repo of team + [] + [] + abstract OrgListTeamRepo : + [] id : int * + [] org : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Remove a repository from a team + [] + [] + abstract OrgRemoveTeamRepository : + [] id : int * + [] org : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Add a repository to a team + [] + [] + abstract OrgAddTeamRepository : + [] id : int * + [] org : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// search topics via keyword + [] + [] + abstract TopicSearch : + [] q : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + TopicResponse list System.Threading.Tasks.Task + + /// Get the authenticated user + [] + [] + abstract UserGetCurrent : ?ct : System.Threading.CancellationToken -> User System.Threading.Tasks.Task + + /// List the authenticated user's oauth2 applications + [] + [] + abstract UserGetOauth2Application : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + OAuth2Application list System.Threading.Tasks.Task + + /// creates a new OAuth2 application + [] + [] + abstract UserCreateOAuth2Application : + [] body : CreateOAuth2ApplicationOptions * ?ct : System.Threading.CancellationToken -> + OAuth2Application System.Threading.Tasks.Task + + /// get an OAuth2 Application + [] + [] + abstract UserGetOAuth2Application : + [] id : int * ?ct : System.Threading.CancellationToken -> + OAuth2Application System.Threading.Tasks.Task + + /// delete an OAuth2 Application + [] + [] + abstract UserDeleteOAuth2Application : + [] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// update an OAuth2 Application, this includes regenerating the client secret + [] + [] + abstract UserUpdateOAuth2Application : + [] id : int * + [] body : CreateOAuth2ApplicationOptions * + ?ct : System.Threading.CancellationToken -> + OAuth2Application System.Threading.Tasks.Task + + /// List the authenticated user's email addresses + [] + [] + abstract UserListEmails : ?ct : System.Threading.CancellationToken -> Email list System.Threading.Tasks.Task + + /// Add email addresses + [] + [] + abstract UserAddEmail : + [] body : CreateEmailOption * ?ct : System.Threading.CancellationToken -> + Email list System.Threading.Tasks.Task + + /// Delete email addresses + [] + [] + abstract UserDeleteEmail : + [] body : DeleteEmailOption * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// List the authenticated user's followers + [] + [] + abstract UserCurrentListFollowers : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// List the users that the authenticated user is following + [] + [] + abstract UserCurrentListFollowing : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check whether a user is followed by the authenticated user + [] + [] + abstract UserCurrentCheckFollowing : + [] username : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Unfollow a user + [] + [] + abstract UserCurrentDeleteFollow : + [] username : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Follow a user + [] + [] + abstract UserCurrentPutFollow : + [] username : string * ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a Token to verify + [] + [] + abstract GetVerificationToken : ?ct : System.Threading.CancellationToken -> string System.Threading.Tasks.Task + + /// Remove a GPG key + [] + [] + abstract UserCurrentDeleteGPGKey : + [] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// List the authenticated user's public keys + [] + [] + abstract UserCurrentListKeys : + [] fingerprint : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + PublicKey list System.Threading.Tasks.Task + + /// Create a public key + [] + [] + abstract UserCurrentPostKey : + [] body : CreateKeyOption * ?ct : System.Threading.CancellationToken -> + PublicKey System.Threading.Tasks.Task + + /// Get a public key + [] + [] + abstract UserCurrentGetKey : + [] id : int * ?ct : System.Threading.CancellationToken -> + PublicKey System.Threading.Tasks.Task + + /// Delete a public key + [] + [] + abstract UserCurrentDeleteKey : + [] id : int * ?ct : System.Threading.CancellationToken -> unit System.Threading.Tasks.Task + + /// List the current user's organizations + [] + [] + abstract OrgListCurrentUserOrgs : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Organization list System.Threading.Tasks.Task + + /// List the repos that the authenticated user owns + [] + [] + abstract UserCurrentListRepos : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// Create a repository + [] + [] + abstract CreateCurrentUserRepo : + [] body : CreateRepoOption * ?ct : System.Threading.CancellationToken -> + Repository System.Threading.Tasks.Task + + /// Get user settings + [] + [] + abstract GetUserSettings : ?ct : System.Threading.CancellationToken -> UserSettings list System.Threading.Tasks.Task + + /// Update user settings + [] + [] + abstract UpdateUserSettings : + [] body : UserSettingsOptions * ?ct : System.Threading.CancellationToken -> + UserSettings list System.Threading.Tasks.Task + + /// The repos that the authenticated user has starred + [] + [] + abstract UserCurrentListStarred : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// Whether the authenticated is starring the repo + [] + [] + abstract UserCurrentCheckStarring : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Unstar the given repo + [] + [] + abstract UserCurrentDeleteStar : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Star the given repo + [] + [] + abstract UserCurrentPutStar : + [] owner : string * + [] repo : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get list of all existing stopwatches + [] + [] + abstract UserGetStopWatches : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + StopWatch list System.Threading.Tasks.Task + + /// List repositories watched by the authenticated user + [] + [] + abstract UserCurrentListSubscriptions : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// List all the teams a user belongs to + [] + [] + abstract UserListTeams : + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Team list System.Threading.Tasks.Task + + /// List the current user's tracked times + [] + [] + abstract UserCurrentTrackedTimes : + [] page : int * + [] limit : int * + [] since : string * + [] before : string * + ?ct : System.Threading.CancellationToken -> + TrackedTime list System.Threading.Tasks.Task + + /// Search for users + [] + [] + abstract UserSearch : + [] q : string * + [] uid : int * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a user + [] + [] + abstract UserGet : + [] username : string * ?ct : System.Threading.CancellationToken -> + User System.Threading.Tasks.Task + + /// List the given user's followers + [] + [] + abstract UserListFollowers : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// List the users that the given user is following + [] + [] + abstract UserListFollowing : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + User list System.Threading.Tasks.Task + + /// Check if one user is following another user + [] + [] + abstract UserCheckFollowing : + [] username : string * + [] target : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Get a user's heatmap + [] + [] + abstract UserGetHeatmapData : + [] username : string * ?ct : System.Threading.CancellationToken -> + UserHeatmapData list System.Threading.Tasks.Task + + /// List the given user's public keys + [] + [] + abstract UserListKeys : + [] username : string * + [] fingerprint : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + PublicKey list System.Threading.Tasks.Task + + /// List a user's organizations + [] + [] + abstract OrgListUserOrgs : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Organization list System.Threading.Tasks.Task + + /// Get user permissions in organization + [] + [] + abstract OrgGetUserPermissions : + [] username : string * + [] org : string * + ?ct : System.Threading.CancellationToken -> + OrganizationPermissions System.Threading.Tasks.Task + + /// List the repos owned by the given user + [] + [] + abstract UserListRepos : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// The repos that the given user has starred + [] + [] + abstract UserListStarred : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// List the repositories watched by a user + [] + [] + abstract UserListSubscriptions : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + Repository list System.Threading.Tasks.Task + + /// List the authenticated user's access tokens + [] + [] + abstract UserGetTokens : + [] username : string * + [] page : int * + [] limit : int * + ?ct : System.Threading.CancellationToken -> + AccessToken list System.Threading.Tasks.Task + + /// Create an access token + [] + [] + abstract UserCreateToken : + [] username : string * + [] body : CreateAccessTokenOption * + ?ct : System.Threading.CancellationToken -> + AccessToken System.Threading.Tasks.Task + + /// delete an access token + [] + [] + abstract UserDeleteAccessToken : + [] username : string * + [] token : string * + ?ct : System.Threading.CancellationToken -> + unit System.Threading.Tasks.Task + + /// Returns the version of the Gitea application + [] + [] + abstract GetVersion : ?ct : System.Threading.CancellationToken -> ServerVersion System.Threading.Tasks.Task diff --git a/Gitea.Declarative.Lib/Gitea.Declarative.Lib.fsproj b/Gitea.Declarative.Lib/Gitea.Declarative.Lib.fsproj index bfa5099..703f334 100644 --- a/Gitea.Declarative.Lib/Gitea.Declarative.Lib.fsproj +++ b/Gitea.Declarative.Lib/Gitea.Declarative.Lib.fsproj @@ -20,19 +20,27 @@ + + + swagger.v1.json + + public + GiteaClient + + + + GeneratedSwaggerGitea.fs + + - - - - diff --git a/Gitea.Declarative.Lib/Gitea.fs b/Gitea.Declarative.Lib/Gitea.fs index d57df56..877c27a 100644 --- a/Gitea.Declarative.Lib/Gitea.fs +++ b/Gitea.Declarative.Lib/Gitea.fs @@ -1,6 +1,7 @@ namespace Gitea.Declarative open System +open System.Collections.Generic open Microsoft.Extensions.Logging type AlignmentError<'a> = @@ -19,19 +20,28 @@ module Gitea = let checkUsers (config : GiteaConfig) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) : Async>>> = async { let desiredUsers = config.Users let! actualUsers = - Array.getPaginated (fun page limit -> - client.AdminGetAllUsers (Some page, Some limit) |> Async.AwaitTask + List.getPaginated (fun page limit -> + async { + let! ct = Async.CancellationToken + return! client.AdminGetAllUsers (page, limit, ct) |> Async.AwaitTask + } ) let actualUsers = - actualUsers |> Seq.map (fun u -> User u.Login, UserInfo.Render u) |> Map.ofSeq + actualUsers + |> Seq.map (fun u -> + match u.Login with + | None -> failwith "Gitea presented a user with no login!" + | Some login -> User login, UserInfo.Render u + ) + |> Map.ofSeq let errors = actualUsers @@ -69,7 +79,7 @@ module Gitea = let checkRepos (logger : ILogger) (config : GiteaConfig) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) : Async>>>> = async { @@ -81,8 +91,11 @@ module Gitea = async { let! repos = - Array.getPaginated (fun page count -> - client.UserListRepos (user, Some page, Some count) |> Async.AwaitTask + List.getPaginated (fun page count -> + async { + let! ct = Async.CancellationToken + return! client.UserListRepos (user, page, count, ct) |> Async.AwaitTask + } ) let! actualRepos = @@ -90,7 +103,10 @@ module Gitea = |> Seq.map (fun repo -> async { let! rendered = Repo.Render client repo - return RepoName repo.Name, rendered + + match repo.Name with + | None -> return failwith "Gitea presented us with a repo with no name!" + | Some repoName -> return RepoName repoName, rendered } ) |> Async.Parallel @@ -149,19 +165,19 @@ module Gitea = Error (Map.ofArray errors) } - let private createPushMirrorOption (target : Uri) (githubToken : string) : Gitea.CreatePushMirrorOption = - let options = Gitea.CreatePushMirrorOption () - options.SyncOnCommit <- Some true - options.RemoteAddress <- target.ToString () - options.RemoteUsername <- githubToken - options.RemotePassword <- githubToken - options.Interval <- "8h0m0s" - - options + let private createPushMirrorOption (target : Uri) (githubToken : string) : GiteaClient.CreatePushMirrorOption = + { + SyncOnCommit = Some true + RemoteAddress = (target : Uri).ToString () |> Some + RemoteUsername = Some githubToken + RemotePassword = Some githubToken + Interval = Some "8h0m0s" + AdditionalProperties = Dictionary () + } let reconcileDifferingConfiguration (logger : ILogger) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) (githubApiToken : string option) (user : string) (repoName : string) @@ -172,7 +188,8 @@ module Gitea = if desired.Deleted = Some true then async { logger.LogWarning ("Deleting repo {User}:{Repo}", user, repoName) - return! Async.AwaitTask (client.RepoDelete (user, repoName)) + let! ct = Async.CancellationToken + return! Async.AwaitTask (client.RepoDelete (user, repoName, ct)) } else @@ -196,7 +213,6 @@ module Gitea = | Some desiredGitHub, Some actualGitHub -> async { let mutable hasChanged = false - let options = Gitea.EditRepoOption () if desiredGitHub.Uri <> actualGitHub.Uri then logger.LogError ( @@ -207,164 +223,181 @@ module Gitea = actualGitHub.Uri ) - if desiredGitHub.MirrorInterval <> actualGitHub.MirrorInterval then - logger.LogDebug ("On {User}:{Repo}, setting {Property}", user, repoName, "MirrorInterval") - options.MirrorInterval <- desiredGitHub.MirrorInterval - hasChanged <- true + let options : GiteaClient.EditRepoOption = + { + AdditionalProperties = Dictionary () + AllowManualMerge = None + AllowMergeCommits = None + AllowRebase = None + AllowRebaseExplicit = None + AllowRebaseUpdate = None + AllowSquashMerge = None + Archived = None + AutodetectManualMerge = None + DefaultAllowMaintainerEdit = None + DefaultBranch = None + DefaultDeleteBranchAfterMerge = None + DefaultMergeStyle = None + EnablePrune = None + ExternalTracker = None + ExternalWiki = None + HasIssues = None + HasProjects = None + HasPullRequests = None + HasWiki = None + IgnoreWhitespaceConflicts = None + InternalTracker = None + MirrorInterval = + if desiredGitHub.MirrorInterval <> actualGitHub.MirrorInterval then + logger.LogDebug ( + "On {User}:{Repo}, setting {Property}", + user, + repoName, + "MirrorInterval" + ) - if desired.Description <> actual.Description then - logger.LogDebug ("On {User}:{Repo}, setting {Property}", user, repoName, "Description") - options.Description <- desired.Description - hasChanged <- true + hasChanged <- true + + Some desiredGitHub.MirrorInterval + Name = None + Private = None + Template = None + Website = None + Description = + if desired.Description <> actual.Description then + logger.LogDebug ("On {User}:{Repo}, setting {Property}", user, repoName, "Description") + hasChanged <- true + + Some desired.Description + } if hasChanged then - let! result = client.RepoEdit (user, repoName, options) |> Async.AwaitTask + let! ct = Async.CancellationToken + let! _result = client.RepoEdit (user, repoName, options, ct) |> Async.AwaitTask return () } | None, None -> async { let mutable hasChanged = false - let options = Gitea.EditRepoOption () - if desired.Description <> actual.Description then - options.Description <- desired.Description - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "Description") - hasChanged <- true - - let desired = + let desired' = match desired.Native with | None -> failwith $"Expected a native section of desired for {user}:{repoName} since there was no GitHub, but got None" | Some n -> n - let actual = + let actual' = match actual.Native with | None -> failwith $"Expected a native section of actual for {user}:{repoName} since there was no GitHub, but got None" | Some n -> n - if desired.Private <> actual.Private then - options.Private <- desired.Private - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "Private") - hasChanged <- true + let setPropertyIfNecessary (desired : 'a option) (actual : 'a option) (propertyName : string) : 'a option = + match desired, actual with + | None, None -> None + | None, Some v -> + // This has been taken out of our management; do nothing. + logger.LogDebug ( + "On {User}:{Repo}, no longer managing {Property} property (value: {CurrentValue})", + user, + repoName, + propertyName, + v + ) - if desired.AllowRebase <> actual.AllowRebase then - options.AllowRebase <- desired.AllowRebase - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "AllowRebase") - hasChanged <- true + None + | Some desired', _ -> + if Some desired' <> actual then + logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, propertyName) + hasChanged <- true - if desired.DefaultBranch <> actual.DefaultBranch then - options.DefaultBranch <- desired.DefaultBranch + Some desired' - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "DefaultBranch") + let setProperty (desired : 'a) (actual : 'a) (propertyName : string) : 'a = + if desired <> actual then + logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, propertyName) + hasChanged <- true - hasChanged <- true + desired - if desired.HasIssues <> actual.HasIssues then - options.HasIssues <- desired.HasIssues - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "HasIssues") - hasChanged <- true + let options : GiteaClient.EditRepoOption = + { + AdditionalProperties = Dictionary () + AllowManualMerge = None + AllowMergeCommits = + setPropertyIfNecessary desired'.AllowMergeCommits actual'.AllowMergeCommits "AllowMergeCommits" + AllowRebase = setPropertyIfNecessary desired'.AllowRebase actual'.AllowRebase "AllowRebase" + AllowRebaseExplicit = + setPropertyIfNecessary + desired'.AllowRebaseExplicit + actual'.AllowRebaseExplicit + "AllowRebaseExplicit" + AllowRebaseUpdate = + setPropertyIfNecessary desired'.AllowRebaseUpdate actual'.AllowRebaseUpdate "AllowRebaseUpdate" + AllowSquashMerge = + setPropertyIfNecessary desired'.AllowSquashMerge actual'.AllowSquashMerge "AllowSquashMerge" + Archived = None + AutodetectManualMerge = None + DefaultAllowMaintainerEdit = None + DefaultBranch = setProperty desired'.DefaultBranch actual'.DefaultBranch "DefaultBranch" |> Some - if desired.HasProjects <> actual.HasProjects then - options.HasProjects <- desired.HasProjects - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "HasProjects") - hasChanged <- true + DefaultDeleteBranchAfterMerge = + setPropertyIfNecessary + desired'.DeleteBranchAfterMerge + actual'.DeleteBranchAfterMerge + "DeleteBranchAfterMerge" - if desired.HasWiki <> actual.HasWiki then - options.HasWiki <- desired.HasWiki - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "HasWiki") - hasChanged <- true + DefaultMergeStyle = + setPropertyIfNecessary desired'.DefaultMergeStyle actual'.DefaultMergeStyle "DefaultMergeStyle" + |> Option.map (fun ms -> (ms : MergeStyle).ToString ()) - if desired.HasPullRequests <> actual.HasPullRequests then - options.HasPullRequests <- desired.HasPullRequests + Description = + setPropertyIfNecessary (Some desired.Description) (Some actual.Description) "Description" - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "HasPullRequests") + EnablePrune = None + ExternalTracker = None + ExternalWiki = None + HasIssues = setPropertyIfNecessary desired'.HasIssues actual'.HasIssues "HasIssues" - hasChanged <- true + HasProjects = setPropertyIfNecessary desired'.HasProjects actual'.HasProjects "HasProjects" - if desired.AllowMergeCommits <> actual.AllowMergeCommits then - options.AllowMergeCommits <- desired.AllowMergeCommits + HasPullRequests = + setPropertyIfNecessary desired'.HasPullRequests actual'.HasPullRequests "HasPullRequests" - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "AllowMergeCommits") + HasWiki = setPropertyIfNecessary desired'.HasWiki actual'.HasWiki "HasWiki" - hasChanged <- true + IgnoreWhitespaceConflicts = + setPropertyIfNecessary + desired'.IgnoreWhitespaceConflicts + actual'.IgnoreWhitespaceConflicts + "IgnoreWhitespaceConflicts" - if desired.AllowRebaseExplicit <> actual.AllowRebaseExplicit then - options.AllowRebaseExplicit <- desired.AllowRebaseExplicit + InternalTracker = None + MirrorInterval = None + Name = None + Private = setPropertyIfNecessary desired'.Private actual'.Private "Private" - logger.LogDebug ( - "On {User}:{Repo}, will set {Property} property", - user, - repoName, - "AllowRebaseExplicit" - ) + Template = None + Website = None - hasChanged <- true + } - if desired.AllowRebase <> actual.AllowRebase then - options.AllowRebase <- desired.AllowRebase - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "AllowRebase") - hasChanged <- true - - if desired.AllowRebaseUpdate <> actual.AllowRebaseUpdate then - options.AllowRebaseUpdate <- desired.AllowRebaseUpdate - - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "AllowRebaseUpdate") - - hasChanged <- true - - if desired.AllowSquashMerge <> actual.AllowSquashMerge then - options.AllowSquashMerge <- desired.AllowSquashMerge - - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "AllowSquashMerge") - - hasChanged <- true - - if desired.DefaultMergeStyle <> actual.DefaultMergeStyle then - options.DefaultMergeStyle <- desired.DefaultMergeStyle |> Option.map MergeStyle.toString |> Option.toObj - - logger.LogDebug ("On {User}:{Repo}, will set {Property} property", user, repoName, "DefaultMergeStyle") - - hasChanged <- true - - if desired.IgnoreWhitespaceConflicts <> actual.IgnoreWhitespaceConflicts then - options.IgnoreWhitespaceConflicts <- desired.IgnoreWhitespaceConflicts - - logger.LogDebug ( - "On {User}:{Repo}, will set {Property} property", - user, - repoName, - "IgnoreWhitespaceConflicts" - ) - - hasChanged <- true - - if desired.DeleteBranchAfterMerge <> actual.DeleteBranchAfterMerge then - options.DefaultDeleteBranchAfterMerge <- desired.DeleteBranchAfterMerge - - logger.LogDebug ( - "On {User}:{Repo}, will set {Property} property", - user, - repoName, - "DeleteBranchAfterMerge" - ) - - hasChanged <- true + let! ct = Async.CancellationToken do! if hasChanged then logger.LogInformation ("Editing repo {User}:{Repo}", user, repoName) - client.RepoEdit (user, repoName, options) |> Async.AwaitTask |> Async.Ignore + client.RepoEdit (user, repoName, options, ct) |> Async.AwaitTask |> Async.Ignore else async.Return () // Push mirrors do! let desired = - desired.Mirrors + desired'.Mirrors |> List.groupBy (fun m -> (m.GitHubAddress : Uri).ToString ()) |> Map.ofList @@ -374,7 +407,7 @@ module Gitea = |> Seq.map (fun (name, pm) -> match pm with | [] -> failwith "LOGIC ERROR" - | [ pm ] -> pm.GitHubAddress.ToString () + | [ pm ] -> (pm.GitHubAddress : Uri).ToString () | _ -> failwith $"Config validation failed on repo %s{repoName}: multiple push mirrors configured for target %s{name}" @@ -382,7 +415,7 @@ module Gitea = |> Set.ofSeq let actual = - actual.Mirrors + actual'.Mirrors |> List.groupBy (fun m -> (m.GitHubAddress : Uri).ToString ()) |> Map.ofList @@ -408,7 +441,7 @@ module Gitea = let! ct = Async.CancellationToken // sigh, domain model - it's *such* a faff to represent this correctly though do! - client.RepoDeletePushMirror (user, repoName, Option.get pm.RemoteName) + client.RepoDeletePushMirror (user, repoName, Option.get pm.RemoteName, ct) |> Async.AwaitTask } ) @@ -424,6 +457,7 @@ module Gitea = | _ -> Map.empty let distinctActual = actual.Keys |> Set.ofSeq + let presentButNotDesired = Set.difference distinctActual desired let desiredButNotPresent = Set.difference desired distinctActual @@ -445,14 +479,15 @@ module Gitea = let! ct = Async.CancellationToken do! - client.RepoDeletePushMirror (user, repoName, Option.get pm.RemoteName) + client.RepoDeletePushMirror (user, repoName, Option.get pm.RemoteName, ct) |> Async.AwaitTask } ) |> Async.Sequential |> Async.map (Array.iter id) ) - |> Seq.toList + |> Async.Sequential + |> Async.map (Array.iter id) let addDesired = desiredButNotPresent @@ -472,26 +507,29 @@ module Gitea = let! ct = Async.CancellationToken let pushMirrorOption = createPushMirrorOption (Uri toAdd) token - let! _ = client.RepoAddPushMirror (user, repoName, pushMirrorOption) |> Async.AwaitTask + let! _ = + client.RepoAddPushMirror (user, repoName, pushMirrorOption, ct) + |> Async.AwaitTask return () } ) - |> Seq.toList + |> Async.Sequential + |> Async.map (Array.iter id) - if deleteExisting.IsEmpty && deleteUndesired.IsEmpty && addDesired.IsEmpty then - async.Return () - else - async { - do! deleteExisting |> Async.Sequential |> Async.map (Array.iter id) - do! deleteUndesired |> Async.Sequential |> Async.map (Array.iter id) - do! addDesired |> Async.Sequential |> Async.map (Array.iter id) - } + async { + do! deleteExisting |> Async.Sequential |> Async.map (Array.iter id) + do! deleteUndesired + do! addDesired + } // Collaborators do! - let desiredButNotPresent = Set.difference desired.Collaborators actual.Collaborators - let presentButNotDesired = Set.difference actual.Collaborators desired.Collaborators + let desiredButNotPresent = + Set.difference desired'.Collaborators actual'.Collaborators + + let presentButNotDesired = + Set.difference actual'.Collaborators desired'.Collaborators [| desiredButNotPresent @@ -504,7 +542,17 @@ module Gitea = repoName ) - do! client.RepoAddCollaborator (user, repoName, desired) |> Async.AwaitTask + let option : GiteaClient.AddCollaboratorOption = + { + AdditionalProperties = Dictionary () + Permission = None + } + + let! ct = Async.CancellationToken + + do! + client.RepoAddCollaborator (user, repoName, desired, option, ct) + |> Async.AwaitTask } ) |> Async.Parallel @@ -520,7 +568,8 @@ module Gitea = repoName ) - do! client.RepoDeleteCollaborator (user, repoName, desired) |> Async.AwaitTask + let! ct = Async.CancellationToken + do! client.RepoDeleteCollaborator (user, repoName, desired, ct) |> Async.AwaitTask } ) |> Async.Parallel @@ -534,10 +583,10 @@ module Gitea = // The current behaviour is kind of desirable, because it gives you a chance to push to // the protected branch before it becomes protected. let extraActualProtected = - Set.difference actual.ProtectedBranches desired.ProtectedBranches + Set.difference actual'.ProtectedBranches desired'.ProtectedBranches let extraDesiredProtected = - Set.difference desired.ProtectedBranches actual.ProtectedBranches + Set.difference desired'.ProtectedBranches actual'.ProtectedBranches Seq.append (Seq.map Choice1Of2 extraActualProtected) (Seq.map Choice2Of2 extraDesiredProtected) |> Seq.groupBy (fun b -> @@ -558,8 +607,10 @@ module Gitea = repoName ) + let! ct = Async.CancellationToken + let! _ = - client.RepoDeleteBranchProtection (user, repoName, x.BranchName) + client.RepoDeleteBranchProtection (user, repoName, x.BranchName, ct) |> Async.AwaitTask return () @@ -574,11 +625,36 @@ module Gitea = repoName ) - let s = Gitea.CreateBranchProtectionOption () - s.BranchName <- y.BranchName - s.RuleName <- y.BranchName - s.BlockOnOutdatedBranch <- y.BlockOnOutdatedBranch - let! _ = client.RepoCreateBranchProtection (user, repoName, s) |> Async.AwaitTask + let s : GiteaClient.CreateBranchProtectionOption = + { + AdditionalProperties = Dictionary () + ApprovalsWhitelistTeams = None + ApprovalsWhitelistUsername = None + BlockOnOfficialReviewRequests = None + BlockOnOutdatedBranch = y.BlockOnOutdatedBranch + BlockOnRejectedReviews = None + BranchName = Some y.BranchName + DismissStaleApprovals = None + EnableApprovalsWhitelist = None + EnableMergeWhitelist = None + EnablePush = None + EnablePushWhitelist = None + EnableStatusCheck = None + MergeWhitelistTeams = None + MergeWhitelistUsernames = None + ProtectedFilePatterns = None + PushWhitelistDeployKeys = None + PushWhitelistTeams = None + PushWhitelistUsernames = None + RequireSignedCommits = None + RequiredApprovals = None + RuleName = Some y.BranchName + StatusCheckContexts = None + UnprotectedFilePatterns = None + } + + let! ct = Async.CancellationToken + let! _ = client.RepoCreateBranchProtection (user, repoName, s, ct) |> Async.AwaitTask return () } | [ Choice1Of2 x ; Choice2Of2 y ] @@ -592,17 +668,41 @@ module Gitea = repoName ) - let s = Gitea.EditBranchProtectionOption () - s.BlockOnOutdatedBranch <- y.BlockOnOutdatedBranch + let statusCheck, contents = + match y.RequiredStatusChecks with + | None -> false, None + | Some checks -> true, Some checks - match y.RequiredStatusChecks with - | None -> s.EnableStatusCheck <- Some false - | Some checks -> - s.EnableStatusCheck <- Some true - s.StatusCheckContexts <- Array.ofList checks + let s : GiteaClient.EditBranchProtectionOption = + { + AdditionalProperties = Dictionary () + ApprovalsWhitelistTeams = None + ApprovalsWhitelistUsername = None + BlockOnOfficialReviewRequests = None + BlockOnOutdatedBranch = y.BlockOnOutdatedBranch + BlockOnRejectedReviews = None + DismissStaleApprovals = None + EnableApprovalsWhitelist = None + EnableMergeWhitelist = None + EnablePush = None + EnablePushWhitelist = None + EnableStatusCheck = Some statusCheck + MergeWhitelistTeams = None + MergeWhitelistUsernames = None + ProtectedFilePatterns = None + PushWhitelistDeployKeys = None + PushWhitelistTeams = None + PushWhitelistUsernames = None + RequireSignedCommits = None + RequiredApprovals = None + StatusCheckContexts = contents + UnprotectedFilePatterns = None + } + + let! ct = Async.CancellationToken let! _ = - client.RepoEditBranchProtection (user, repoName, y.BranchName, s) + client.RepoEditBranchProtection (user, repoName, y.BranchName, s, ct) |> Async.AwaitTask return () @@ -617,7 +717,7 @@ module Gitea = let reconcileRepoErrors (logger : ILogger) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) (githubApiToken : string option) (m : Map>>) : Async @@ -634,14 +734,28 @@ module Gitea = logger.LogDebug ("Creating {User}:{Repo}", user, r) match desired.GitHub, desired.Native with + | None, None -> failwith $"You must supply exactly one of Native or GitHub for {user}:{r}." + | Some _, Some _ -> + failwith $"Repo {user}:{r} has both Native and GitHub set; you must set exactly one." | None, Some native -> - let options = Gitea.CreateRepoOption () - options.Description <- desired.Description - options.Name <- r - options.Private <- native.Private - options.DefaultBranch <- native.DefaultBranch + let options : GiteaClient.CreateRepoOption = + { + AdditionalProperties = Dictionary () + AutoInit = None + DefaultBranch = Some native.DefaultBranch + Description = Some desired.Description + Gitignores = None + IssueLabels = None + License = None + Name = r + Private = native.Private + Readme = None + Template = None + TrustModel = None + } - let! result = client.AdminCreateRepo (user, options) |> Async.AwaitTask |> Async.Catch + let! ct = Async.CancellationToken + let! result = client.AdminCreateRepo (user, options, ct) |> Async.AwaitTask |> Async.Catch match result with | Choice2Of2 e -> raise (AggregateException ($"Error creating {user}:{r}", e)) @@ -654,24 +768,33 @@ module Gitea = logger.LogInformation ("Setting up push mirror for {User}:{Repo}", user, r) let! actualMirrors = - getAllPaginated (fun page count -> - client.RepoListPushMirrors (user, r, Some page, Some count) + List.getPaginated (fun page count -> + async { + let! ct = Async.CancellationToken + + return! + client.RepoListPushMirrors (user, r, page, count, ct) + |> Async.AwaitTask + } ) do! mirrors |> List.map (fun mirror -> - let options = Gitea.CreatePushMirrorOption () - options.SyncOnCommit <- Some true - options.RemoteAddress <- (mirror.GitHubAddress : Uri).ToString () - options.RemoteUsername <- token - options.RemotePassword <- token - options.Interval <- "8h0m0s" + let options : GiteaClient.CreatePushMirrorOption = + { + AdditionalProperties = Dictionary () + Interval = Some "8h0m0s" + RemoteAddress = (mirror.GitHubAddress : Uri).ToString () |> Some + RemotePassword = Some token + RemoteUsername = Some token + SyncOnCommit = Some true + } async { match actualMirrors - |> Array.tryFind (fun m -> m.RemoteAddress = options.RemoteAddress) + |> List.tryFind (fun m -> m.RemoteAddress = options.RemoteAddress) with | None -> let! _ = @@ -686,32 +809,38 @@ module Gitea = |> Async.Sequential |> Async.map (Array.iter id) - () | Some github, None -> - let options = Gitea.MigrateRepoOptions () - options.Description <- desired.Description - options.Mirror <- Some true - options.RepoName <- r - options.RepoOwner <- user - options.CloneAddr <- string github.Uri - options.Issues <- Some true - options.Labels <- Some true - options.Lfs <- Some true - options.Milestones <- Some true - options.Releases <- Some true - options.Wiki <- Some true - options.PullRequests <- Some true - // TODO - migrate private status - githubApiToken |> Option.iter (fun t -> options.AuthToken <- t) + let options : GiteaClient.MigrateRepoOptions = + { + AdditionalProperties = Dictionary () + AuthPassword = None + AuthToken = githubApiToken + AuthUsername = None + CloneAddr = string github.Uri + Issues = Some true + Labels = Some true + Lfs = Some true + LfsEndpoint = None + Milestones = Some true + Mirror = Some true + MirrorInterval = Some "8h0m0s" + // TODO - migrate private status + Private = None + PullRequests = Some true + Releases = Some true + RepoName = r + RepoOwner = Some user + Service = None + Uid = None + Wiki = Some true + Description = Some desired.Description + } let! result = client.RepoMigrate options |> Async.AwaitTask |> Async.Catch match result with | Choice2Of2 e -> raise (AggregateException ($"Error migrating {user}:{r}", e)) | Choice1Of2 _ -> () - | None, None -> failwith $"You must supply exactly one of Native or GitHub for {user}:{r}." - | Some _, Some _ -> - failwith $"Repo {user}:{r} has both Native and GitHub set; you must set exactly one." logger.LogInformation ("Created repo {User}: {Repo}", user, r) @@ -735,10 +864,64 @@ module Gitea = |> Async.Parallel |> fun a -> async.Bind (a, Array.iter id >> async.Return) + let rec constructEditObject + (log : ILogger) + (user : string) + (updates : UserInfoUpdate list) + (body : GiteaClient.EditUserOption) + : GiteaClient.EditUserOption + = + match updates with + | [] -> body + | h :: rest -> + match h with + | UserInfoUpdate.Admin (desired, actual) -> + match desired, actual with + | None, None -> body + | None, Some _ -> + log.LogDebug ("No longer managing property {Property} for user {User}", "Admin", user) + body + | Some desired, _ -> + log.LogDebug ("Editing {User}, property {Property}", user, "Admin") + + { body with + Admin = Some desired + } + | UserInfoUpdate.Email (desired, actual) -> + log.LogDebug ("Editing {User}, property {Property}", user, "Email") + + { body with + Email = Some desired + } + | UserInfoUpdate.Visibility (desired, actual) -> + log.LogDebug ("Editing {User}, property {Property}", user, "Visibility") + + { body with + Visibility = Some desired + } + | UserInfoUpdate.Website (desired, actual) -> + // Per https://github.com/go-gitea/gitea/issues/17126, + // the website parameter can't currently be edited. + // This is a bug that is unlikely to be fixed. + let actual = + match actual with + | None -> "" + | Some uri -> uri.ToString () + + log.LogCritical ( + "User {User} has conflicting website, desired {DesiredWebsite}, existing {ActualWebsite}, which a bug in Gitea means can't be reconciled via the API.", + user, + desired, + actual + ) + + body + |> constructEditObject log user rest + let reconcileUserErrors (log : ILogger) (getUserInput : string -> string) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) (m : Map>) = let userInputLock = obj () @@ -756,19 +939,27 @@ module Gitea = Array.init 15 (fun _ -> rand.Next (65, 65 + 25) |> byte) |> System.Text.Encoding.ASCII.GetString - let options = Gitea.CreateUserOption () - options.Email <- desired.Email - options.Username <- user - options.FullName <- user + let options : GiteaClient.CreateUserOption = + { + AdditionalProperties = Dictionary () + CreatedAt = None + Email = desired.Email + FullName = Some user + LoginName = Some user + MustChangePassword = Some true + Password = pwd + Restricted = None + SendNotify = None + SourceId = None + Username = user + Visibility = + match desired.Visibility with + | None -> Some "public" + | Some v -> Some v - options.Visibility <- - match desired.Visibility with - | None -> "public" - | Some v -> v - options.LoginName <- user - options.MustChangePassword <- Some true - options.Password <- pwd + } + let! _ = client.AdminCreateUser options |> Async.AwaitTask lock @@ -792,7 +983,7 @@ module Gitea = UserInput.getDefaultNo getUserInput $"User %s{user} unexpectedly present. Remove?" if answer then - client.AdminDeleteUser(user).Result + client.AdminDeleteUser(user, false).Result else log.LogCritical ("Refusing to delete user {User}, who is unexpectedly present.", user) ) @@ -804,36 +995,35 @@ module Gitea = lock userInputLock (fun () -> - let body = Gitea.EditUserOption () + let body : GiteaClient.EditUserOption = + { + AdditionalProperties = Dictionary () + Active = None + Admin = None + AllowCreateOrganization = None + AllowGitHook = None + AllowImportLocal = None + Description = None + Email = None + FullName = None + Location = None + LoginName = user + MaxRepoCreation = None + MustChangePassword = None + Password = None + ProhibitLogin = None + Restricted = None + SourceId = + // Wouldn't it be lovely if *any* of this were documented? + // I still have no idea what this does; it's optional when creating a user, + // but mandatory when editing a user. + 0 + Visibility = None + Website = None + } - for update in updates do - match update with - | UserInfoUpdate.Admin (desired, _) -> - log.LogDebug ("Editing {User}, property {Property}", user, "Admin") - body.Admin <- desired - | UserInfoUpdate.Email (desired, _) -> - log.LogDebug ("Editing {User}, property {Property}", user, "Email") - body.Email <- desired - | UserInfoUpdate.Visibility (desired, _) -> - log.LogDebug ("Editing {User}, property {Property}", user, "Visibility") - body.Visibility <- desired - | UserInfoUpdate.Website (desired, actual) -> - // Per https://github.com/go-gitea/gitea/issues/17126, - // the website parameter can't currently be edited. - // This is a bug that is unlikely to be fixed. - let actual = - match actual with - | None -> "" - | Some uri -> uri.ToString () + let body = constructEditObject log user updates body - log.LogCritical ( - "User {User} has conflicting website, desired {DesiredWebsite}, existing {ActualWebsite}, which a bug in Gitea means can't be reconciled via the API.", - user, - desired, - actual - ) - - body.LoginName <- user client.AdminEditUser(user, body).Result |> ignore ) } @@ -841,44 +1031,53 @@ module Gitea = |> Async.Parallel |> fun a -> async.Bind (a, Array.iter id >> async.Return) - let toRefresh (client : IGiteaClient) : Async>> = + let toRefresh (client : GiteaClient.IGiteaClient) : Async>> = async { + let! ct = Async.CancellationToken + let! users = - Array.getPaginated (fun page limit -> - client.AdminGetAllUsers (Some page, Some limit) |> Async.AwaitTask - ) + List.getPaginated (fun page limit -> client.AdminGetAllUsers (page, limit, ct) |> Async.AwaitTask) let! results = users |> Seq.map (fun user -> async { + let loginName = + match user.LoginName with + | None -> failwith "Gitea returned a User with no login name!" + | Some name -> name + + let! ct = Async.CancellationToken + let! repos = - Array.getPaginated (fun page count -> - client.UserListRepos (user.LoginName, Some page, Some count) |> Async.AwaitTask + List.getPaginated (fun page count -> + client.UserListRepos (loginName, page, count, ct) |> Async.AwaitTask ) let! pushMirrorResults = repos |> Seq.map (fun r -> async { + let repoName = + match r.Name with + | None -> failwith "Gitea returned a Repo with no name!" + | Some name -> name + + let! ct = Async.CancellationToken + let! mirrors = - Array.getPaginated (fun page count -> + List.getPaginated (fun page count -> Async.AwaitTask ( - client.RepoListPushMirrors ( - user.LoginName, - r.Name, - Some page, - Some count - ) + client.RepoListPushMirrors (loginName, repoName, page, count, ct) ) ) - return RepoName r.Name, mirrors + return RepoName repoName, mirrors } ) |> Async.Parallel - return User user.LoginName, Map.ofArray pushMirrorResults + return User loginName, Map.ofArray pushMirrorResults } ) |> Async.Parallel @@ -888,39 +1087,58 @@ module Gitea = let refreshAuth (logger : ILogger) - (client : IGiteaClient) + (client : GiteaClient.IGiteaClient) (githubToken : string) - (instructions : Map>) + (instructions : Map>) : Async = instructions |> Map.toSeq |> Seq.collect (fun (User user, repos) -> Map.toSeq repos - |> Seq.collect (fun (RepoName repoName, mirrors) -> + |> Seq.map (fun (RepoName repoName, mirrors) -> mirrors |> Seq.map (fun mirror -> async { + let remoteAddress = + match mirror.RemoteAddress with + | None -> + failwith $"Gitea returned a mirror with no remote address, for repo %s{repoName}!" + | Some remoteAddress -> remoteAddress + + let remoteName = + match mirror.RemoteName with + | None -> failwith $"Gitea returned a mirror with no remote name, for repo %s{repoName}!" + | Some remoteAddress -> remoteAddress + logger.LogInformation ( "Refreshing push mirror on {User}:{Repo} to {PushMirrorRemote}", user, repoName, - mirror.RemoteAddress + remoteAddress ) - let option = createPushMirrorOption (Uri mirror.RemoteAddress) githubToken + let option = + { createPushMirrorOption (Uri remoteAddress) githubToken with + Interval = mirror.Interval + SyncOnCommit = mirror.SyncOnCommit + } - option.Interval <- mirror.Interval - option.SyncOnCommit <- mirror.SyncOnCommit + let! ct = Async.CancellationToken - let! newMirror = Async.AwaitTask (client.RepoAddPushMirror (user, repoName, option)) + let! newMirror = Async.AwaitTask (client.RepoAddPushMirror (user, repoName, option, ct)) let! deleteOldMirror = - Async.AwaitTask (client.RepoDeletePushMirror (user, repoName, mirror.RemoteName)) + Async.AwaitTask (client.RepoDeletePushMirror (user, repoName, remoteName, ct)) + return () } ) + // Gitea will attempt to lock the repo config file for every push mirror, so these have to happen + // serially, on pain of 500 Internal Server Error :facepalm: + |> Async.Sequential + |> Async.map (Array.iter id) ) ) |> Async.Parallel diff --git a/Gitea.Declarative.Lib/GiteaClient.fs b/Gitea.Declarative.Lib/GiteaClient.fs deleted file mode 100644 index 1ec70af..0000000 --- a/Gitea.Declarative.Lib/GiteaClient.fs +++ /dev/null @@ -1,29 +0,0 @@ -namespace Gitea.Declarative - -open System.Threading.Tasks -open SwaggerProvider - -[] -module GiteaClient = - - [] - let Host = "file://" + __SOURCE_DIRECTORY__ + "/swagger.v1.json" - - type Gitea = SwaggerClientProvider - - /// The input function takes page first, then count. - /// Repeatedly calls `f` with increasing page numbers until all results are returned. - let getAllPaginated (f : int64 -> int64 -> 'ret array Task) : 'ret array Async = - let rec go (page : int64) (soFar : 'ret array) = - async { - let! newPage = f page 100L |> Async.AwaitTask - - let soFar = Array.append soFar newPage - - if newPage.Length < 100 then - return soFar - else - return! go (page + 1L) soFar - } - - go 0L [||] diff --git a/Gitea.Declarative.Lib/IGiteaClient.fs b/Gitea.Declarative.Lib/IGiteaClient.fs deleted file mode 100644 index 487c3e1..0000000 --- a/Gitea.Declarative.Lib/IGiteaClient.fs +++ /dev/null @@ -1,90 +0,0 @@ -namespace Gitea.Declarative - -open System.Threading.Tasks - -type IGiteaClient = - abstract AdminGetAllUsers : page : int64 option * limit : int64 option -> Gitea.User array Task - abstract AdminCreateUser : Gitea.CreateUserOption -> Gitea.User Task - abstract AdminDeleteUser : user : string -> unit Task - abstract AdminEditUser : user : string * Gitea.EditUserOption -> Gitea.User Task - abstract AdminCreateRepo : user : string * Gitea.CreateRepoOption -> Gitea.Repository Task - - abstract UserListRepos : string * page : int64 option * count : int64 option -> Gitea.Repository array Task - - abstract RepoAddPushMirror : user : string * repo : string * Gitea.CreatePushMirrorOption -> Gitea.PushMirror Task - - abstract RepoListPushMirrors : - loginName : string * userName : string * page : int64 option * count : int64 option -> - Gitea.PushMirror array Task - - abstract RepoDeletePushMirror : user : string * repo : string * remoteName : string -> unit Task - - abstract RepoListBranchProtection : loginName : string * userName : string -> Gitea.BranchProtection array Task - abstract RepoDeleteBranchProtection : user : string * repo : string * branch : string -> unit Task - - abstract RepoCreateBranchProtection : - user : string * repo : string * Gitea.CreateBranchProtectionOption -> Gitea.BranchProtection Task - - abstract RepoEditBranchProtection : - user : string * repo : string * branch : string * Gitea.EditBranchProtectionOption -> - Gitea.BranchProtection Task - - abstract RepoMigrate : Gitea.MigrateRepoOptions -> Gitea.Repository Task - abstract RepoGet : user : string * repo : string -> Gitea.Repository Task - abstract RepoDelete : user : string * repo : string -> unit Task - abstract RepoEdit : user : string * repo : string * Gitea.EditRepoOption -> Gitea.Repository Task - - abstract RepoListCollaborators : - loginName : string * userName : string * page : int64 option * count : int64 option -> Gitea.User array Task - - abstract RepoAddCollaborator : user : string * repo : string * collaborator : string -> unit Task - abstract RepoDeleteCollaborator : user : string * repo : string * collaborator : string -> unit Task - -[] -module IGiteaClient = - let fromReal (client : Gitea.Client) : IGiteaClient = - { new IGiteaClient with - member _.AdminGetAllUsers (page, limit) = client.AdminGetAllUsers (page, limit) - member _.AdminCreateUser user = client.AdminCreateUser user - member _.AdminDeleteUser user = client.AdminDeleteUser user - member _.AdminEditUser (user, option) = client.AdminEditUser (user, option) - member _.AdminCreateRepo (user, option) = client.AdminCreateRepo (user, option) - - member _.UserListRepos (user, page, count) = - client.UserListRepos (user, page, count) - - member _.RepoAddPushMirror (user, repo, options) = - client.RepoAddPushMirror (user, repo, options) - - member _.RepoListPushMirrors (loginName, userName, page, count) = - client.RepoListPushMirrors (loginName, userName, page, count) - - member _.RepoDeletePushMirror (loginName, repo, remoteName) = - client.RepoDeletePushMirror (loginName, repo, remoteName) - - member _.RepoListBranchProtection (login, user) = - client.RepoListBranchProtection (login, user) - - member _.RepoDeleteBranchProtection (user, repo, branch) = - client.RepoDeleteBranchProtection (user, repo, branch) - - member _.RepoCreateBranchProtection (user, repo, options) = - client.RepoCreateBranchProtection (user, repo, options) - - member _.RepoEditBranchProtection (user, repo, branch, edit) = - client.RepoEditBranchProtection (user, repo, branch, edit) - - member _.RepoMigrate options = client.RepoMigrate options - member _.RepoGet (user, repo) = client.RepoGet (user, repo) - member _.RepoDelete (user, repo) = client.RepoDelete (user, repo) - member _.RepoEdit (user, repo, options) = client.RepoEdit (user, repo, options) - - member _.RepoListCollaborators (login, user, page, count) = - client.RepoListCollaborators (login, user, page, count) - - member _.RepoAddCollaborator (user, repo, collaborator) = - client.RepoAddCollaborator (user, repo, collaborator) - - member _.RepoDeleteCollaborator (user, repo, collaborator) = - client.RepoDeleteCollaborator (user, repo, collaborator) - } diff --git a/Gitea.Declarative.Lib/Array.fs b/Gitea.Declarative.Lib/List.fs similarity index 61% rename from Gitea.Declarative.Lib/Array.fs rename to Gitea.Declarative.Lib/List.fs index 9c8980b..0c3a556 100644 --- a/Gitea.Declarative.Lib/Array.fs +++ b/Gitea.Declarative.Lib/List.fs @@ -1,20 +1,20 @@ namespace Gitea.Declarative [] -module internal Array = +module internal List = /// f takes a page number and a limit (i.e. a desired page size). - let getPaginated (f : int64 -> int64 -> 'a array Async) : 'a list Async = + let getPaginated (f : int -> int -> 'a list Async) : 'a list Async = let count = 30 - let rec go (page : int) (acc : 'a array list) = + let rec go (page : int) (acc : 'a list list) = async { let! result = f page count if result.Length >= count then return! go (page + 1) (result :: acc) else - return (result :: acc) |> Seq.concat |> Seq.toList + return (result :: acc) |> List.concat } go 1 [] diff --git a/Gitea.Declarative.Lib/myriad.toml b/Gitea.Declarative.Lib/myriad.toml new file mode 100644 index 0000000..e69de29 diff --git a/Gitea.Declarative.Test/TestRepo.fs b/Gitea.Declarative.Test/TestRepo.fs index af8887f..ad8f3e7 100644 --- a/Gitea.Declarative.Test/TestRepo.fs +++ b/Gitea.Declarative.Test/TestRepo.fs @@ -15,7 +15,7 @@ module TestRepo = [] let ``We refuse to delete a repo if we get to Reconcile without positive confirmation`` () = let property (gitHubToken : string option) = - let client = GiteaClientMock.Unimplemented + let client = GiteaClient.GiteaClientMock.Empty let lf, messages = LoggerFactory.makeTest () let logger = lf.CreateLogger "test" @@ -42,10 +42,10 @@ module TestRepo = (user : User) (repos : Map) (userInfo : UserInfo) - (repo : Gitea.Repository) - (reposToReturn : Gitea.Repository[]) + (repo : GiteaClient.Repository) + (reposToReturn : GiteaClient.Repository list) = - let reposToReturn = Array.append [| repo |] reposToReturn + let reposToReturn = repo :: reposToReturn let reposToReturn = if reposToReturn.Length >= 5 then @@ -53,25 +53,35 @@ module TestRepo = else reposToReturn + for repo in reposToReturn do + match repo.Name with + | None -> failwith "generator should have put a name on every repo" + | Some _ -> () + let lf, messages = LoggerFactory.makeTest () let logger = lf.CreateLogger "test" let client = - { GiteaClientMock.Unimplemented with + { GiteaClient.GiteaClientMock.Empty with UserListRepos = - fun (_username, _page, _limit) -> + fun (_username, _page, _limit, ct) -> async { return reposToReturn - |> Array.filter (fun r -> not (repos.ContainsKey (RepoName r.Name))) + |> List.filter (fun r -> not (repos.ContainsKey (RepoName (Option.get r.Name)))) } - |> Async.StartAsTask + |> fun a -> Async.StartAsTask (a, ?cancellationToken = ct) - RepoListPushMirrors = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListPushMirrors = + fun (_, _, _, _, ct) -> + async { return [] } |> fun a -> Async.StartAsTask (a, ?cancellationToken = ct) - RepoListBranchProtection = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListBranchProtection = + fun (_, _, ct) -> async { return [] } |> fun a -> Async.StartAsTask (a, ?cancellationToken = ct) - RepoListCollaborators = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListCollaborators = + fun (_, _, _, _, ct) -> + async { return [] } |> fun a -> Async.StartAsTask (a, ?cancellationToken = ct) } let config : GiteaConfig = @@ -121,14 +131,14 @@ module TestRepo = let logger = lf.CreateLogger "test" let client = - { GiteaClientMock.Unimplemented with - UserListRepos = fun _ -> Task.FromResult [||] + { GiteaClient.GiteaClientMock.Empty with + UserListRepos = fun _ -> Task.FromResult [] - RepoListPushMirrors = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListPushMirrors = fun _ -> async { return [] } |> Async.StartAsTask - RepoListBranchProtection = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListBranchProtection = fun _ -> async { return [] } |> Async.StartAsTask - RepoListCollaborators = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListCollaborators = fun _ -> async { return [] } |> Async.StartAsTask } let config : GiteaConfig = @@ -168,13 +178,10 @@ module TestRepo = let existingRepos = existingRepos |> Map.add oneExistingRepoName oneExistingRepo - let giteaUser = - let result = Gitea.User () - result.LoginName <- user.ToString () - result + let giteaUser = Types.emptyUser (user.ToString ()) let client = - { GiteaClientMock.Unimplemented with + { GiteaClient.GiteaClientMock.Empty with UserListRepos = fun _ -> async { @@ -182,20 +189,20 @@ module TestRepo = existingRepos |> Map.toSeq |> Seq.map (fun (RepoName repoName, _repoSpec) -> - let repo = Gitea.Repository () - repo.Name <- repoName - repo.Owner <- giteaUser - repo + { Types.emptyRepo repoName "main" with + Name = Some repoName + Owner = Some giteaUser + } ) - |> Seq.toArray + |> Seq.toList } |> Async.StartAsTask - RepoListPushMirrors = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListPushMirrors = fun _ -> async { return [] } |> Async.StartAsTask - RepoListBranchProtection = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListBranchProtection = fun _ -> async { return [] } |> Async.StartAsTask - RepoListCollaborators = fun _ -> async { return [||] } |> Async.StartAsTask + RepoListCollaborators = fun _ -> async { return [] } |> Async.StartAsTask } let config : GiteaConfig = diff --git a/Gitea.Declarative.Test/TestUser.fs b/Gitea.Declarative.Test/TestUser.fs index 1412a52..9077a4c 100644 --- a/Gitea.Declarative.Test/TestUser.fs +++ b/Gitea.Declarative.Test/TestUser.fs @@ -21,14 +21,14 @@ module TestUser = let result = TaskCompletionSource () let client = - { GiteaClientMock.Unimplemented with + { GiteaClient.GiteaClientMock.Empty with AdminCreateUser = - fun options -> + fun (options, ct) -> async { result.SetResult options.MustChangePassword - return null + return Types.emptyUser "username" } - |> Async.StartAsTask + |> fun a -> Async.StartAsTask (a, ?cancellationToken = ct) } [ User "username", AlignmentError.DoesNotExist desiredUser ] diff --git a/Gitea.Declarative.Test/Utils.fs b/Gitea.Declarative.Test/Utils.fs index 21d5362..ee3e536 100644 --- a/Gitea.Declarative.Test/Utils.fs +++ b/Gitea.Declarative.Test/Utils.fs @@ -1,108 +1,200 @@ namespace Gitea.Declarative.Test +open System.Collections.Generic open Gitea.Declarative open System open System.IO open FsCheck open Microsoft.FSharp.Reflection +[] +module Types = + let emptyUser (loginName : string) : GiteaClient.User = + { + Active = None + Created = None + Description = None + Email = None + Id = None + Language = None + Location = None + Login = None + Restricted = None + Visibility = None + Website = None + FullName = None + IsAdmin = None + LoginName = Some loginName + ProhibitLogin = None + AdditionalProperties = Dictionary () + AvatarUrl = None + FollowersCount = None + FollowingCount = None + StarredReposCount = None + LastLogin = None + } + + let emptyRepo (fullName : string) (defaultBranch : string) : GiteaClient.Repository = + { + Archived = None + Description = Some "a description here" + Empty = None + Fork = None + Id = None + Internal = None + Language = None + Link = None + Mirror = None + Name = None + Owner = Some (emptyUser "some-username") + Private = None + Website = None + AllowRebase = None + AllowMergeCommits = None + AllowRebaseExplicit = None + AllowRebaseUpdate = None + AllowSquashMerge = None + DefaultBranch = Some defaultBranch + HasIssues = None + HasProjects = None + HasWiki = None + HasPullRequests = None + DefaultMergeStyle = None + AdditionalProperties = Dictionary () + AvatarUrl = None + CloneUrl = None + CreatedAt = None + DefaultAllowMaintainerEdit = None + DefaultDeleteBranchAfterMerge = None + ExternalTracker = None + ExternalWiki = None + ForksCount = None + FullName = Some fullName + HtmlUrl = None + IgnoreWhitespaceConflicts = None + InternalTracker = None + LanguagesUrl = None + MirrorInterval = None + MirrorUpdated = None + OpenIssuesCount = None + OpenPrCounter = None + OriginalUrl = None + Parent = None + Permissions = None + ReleaseCounter = None + RepoTransfer = None + Size = None + SshUrl = None + StarsCount = None + Template = None + UpdatedAt = None + WatchersCount = None + } + type CustomArb () = static member UriGen = Gen.constant (Uri "http://example.com") |> Arb.fromGen - static member User : Arbitrary = + static member User : Arbitrary = gen { - let user = Gitea.User () - let! a = Arb.generate<_> - user.Active <- a - let! a = Arb.generate<_> - user.Created <- a - let! a = Arb.generate<_> - user.Description <- a - let! a = Arb.generate<_> - user.Email <- a - let! a = Arb.generate<_> - user.Id <- a - let! a = Arb.generate<_> - user.Language <- a - let! a = Arb.generate<_> - user.Location <- a - let! a = Arb.generate<_> - user.Login <- a - let! a = Arb.generate<_> - user.Restricted <- a - let! a = Arb.generate<_> - user.Visibility <- a - let! a = Arb.generate<_> - user.Website <- a - let! a = Arb.generate<_> - user.FullName <- a - let! a = Arb.generate<_> - user.IsAdmin <- a - let! a = Arb.generate<_> - user.LoginName <- a - let! a = Arb.generate<_> - user.ProhibitLogin <- a - return user + let! active = Arb.generate<_> + let! created = Arb.generate<_> + let! description = Arb.generate<_> + let! email = Arb.generate<_> + let! id = Arb.generate<_> + let! language = Arb.generate<_> + let! location = Arb.generate<_> + let! login = Arb.generate<_> + let! restricted = Arb.generate<_> + let! visibility = Arb.generate<_> + let! website = Arb.generate<_> + let! fullname = Arb.generate<_> + let! isAdmin = Arb.generate<_> + let! loginName = Arb.generate<_> + let! prohibitLogin = Arb.generate<_> + + return + ({ Types.emptyUser loginName with + Active = active + Created = created + Description = description + Email = email + Id = id + Language = language + Location = location + Login = login + Restricted = restricted + Visibility = visibility + Website = website + FullName = fullname + IsAdmin = isAdmin + ProhibitLogin = prohibitLogin + } + : GiteaClient.User) } |> Arb.fromGen - static member RepositoryGen : Arbitrary = + static member RepositoryGen : Arbitrary = gen { - let repo = Gitea.Repository () - let! a = Arb.generate<_> - repo.Archived <- a - let! a = Arb.generate<_> - repo.Description <- a - let! a = Arb.generate<_> - repo.Empty <- a - let! a = Arb.generate<_> - repo.Fork <- a - let! a = Arb.generate<_> - repo.Id <- a - let! a = Arb.generate<_> - repo.Internal <- a - let! a = Arb.generate<_> - repo.Language <- a - let! a = Arb.generate<_> - repo.Link <- a - let! a = Arb.generate<_> - repo.Mirror <- a - let! a = Arb.generate<_> - repo.Name <- a - let! a = Arb.generate<_> - repo.Owner <- a - let! a = Arb.generate<_> - repo.Private <- a - let! a = Arb.generate<_> - repo.Website <- a - let! a = Arb.generate<_> - repo.AllowRebase <- a - let! a = Arb.generate<_> - repo.AllowMergeCommits <- a - let! a = Arb.generate<_> - repo.AllowRebaseExplicit <- a - let! a = Arb.generate<_> - repo.AllowRebaseUpdate <- a - let! a = Arb.generate<_> - repo.AllowSquashMerge <- a - let! a = Arb.generate<_> - repo.DefaultBranch <- a - let! a = Arb.generate<_> - repo.HasIssues <- a - let! a = Arb.generate<_> - repo.HasProjects <- a - let! a = Arb.generate<_> - repo.HasWiki <- a - let! a = Arb.generate<_> - repo.HasPullRequests <- a + let! archived = Arb.generate<_> + let! description = Arb.generate<_> + let! empty = Arb.generate<_> + let! fork = Arb.generate<_> + let! id = Arb.generate<_> + let! isInternal = Arb.generate<_> + let! language = Arb.generate<_> + let! link = Arb.generate<_> + let! mirror = Arb.generate<_> + let! name = Arb.generate<_> + let! fullName = Arb.generate<_> + let! owner = Arb.generate<_> + let! isPrivate = Arb.generate<_> + let! website = Arb.generate<_> + let! allowRebase = Arb.generate<_> + let! allowMergeCommits = Arb.generate<_> + let! allowRebaseExplicit = Arb.generate<_> + let! allowRebaseUpdate = Arb.generate<_> + let! allowSquashMerge = Arb.generate<_> + let! defaultBranch = Arb.generate<_> + let! hasIssues = Arb.generate<_> + let! hasProjects = Arb.generate<_> + let! hasWiki = Arb.generate<_> + let! hasPullRequests = Arb.generate<_> - let! a = + let! mergeStyle = FSharpType.GetUnionCases typeof |> Array.map (fun uci -> FSharpValue.MakeUnion (uci, [||]) |> unbox) |> Gen.elements - repo.DefaultMergeStyle <- MergeStyle.toString a - return repo + let mergeStyle = (mergeStyle : MergeStyle).ToString () + + return + ({ Types.emptyRepo fullName defaultBranch with + Archived = archived + Description = Some description + Empty = empty + Fork = fork + Id = id + Internal = isInternal + Language = language + Link = link + Mirror = mirror + Name = Some name + Owner = Some owner + Private = isPrivate + Website = website + AllowRebase = allowRebase + AllowMergeCommits = allowMergeCommits + AllowRebaseExplicit = allowRebaseExplicit + AllowRebaseUpdate = allowRebaseUpdate + AllowSquashMerge = allowSquashMerge + HasIssues = hasIssues + HasProjects = hasProjects + HasWiki = hasWiki + HasPullRequests = hasPullRequests + DefaultMergeStyle = Some mergeStyle + AdditionalProperties = Dictionary () + } + : GiteaClient.Repository) } |> Arb.fromGen diff --git a/Gitea.Declarative/Reconcile.fs b/Gitea.Declarative/Reconcile.fs index da1158f..f9ac382 100644 --- a/Gitea.Declarative/Reconcile.fs +++ b/Gitea.Declarative/Reconcile.fs @@ -63,7 +63,7 @@ module Reconcile = let logger = loggerProvider.CreateLogger "Gitea.Declarative" use httpClient = Utils.createHttpClient args.GiteaHost args.GiteaAdminApiToken - let client = Gitea.Client httpClient |> IGiteaClient.fromReal + let client = GiteaClient.GiteaClient.make httpClient logger.LogInformation "Checking users..." let! userErrors = Gitea.checkUsers config client diff --git a/Gitea.Declarative/RefreshAuth.fs b/Gitea.Declarative/RefreshAuth.fs index 94eae1d..77c8d8b 100644 --- a/Gitea.Declarative/RefreshAuth.fs +++ b/Gitea.Declarative/RefreshAuth.fs @@ -50,7 +50,7 @@ module RefreshAuth = let run (args : RefreshAuthArgs) : Async = async { use httpClient = Utils.createHttpClient args.GiteaHost args.GiteaAdminApiToken - let client = Gitea.Client httpClient |> IGiteaClient.fromReal + let client = GiteaClient.GiteaClient.make httpClient use loggerProvider = Utils.createLoggerProvider () let logger = loggerProvider.CreateLogger "Gitea.Declarative" @@ -58,7 +58,7 @@ module RefreshAuth = let! instructions = Gitea.toRefresh client if args.DryRun then - logger.LogInformation ("Stopping due to --dry-run.") + logger.LogInformation "Stopping due to --dry-run." else do! Gitea.refreshAuth logger client args.GitHubApiToken instructions diff --git a/Gitea.InMemory/Client.fs b/Gitea.InMemory/Client.fs index 83109d8..effb3c1 100644 --- a/Gitea.InMemory/Client.fs +++ b/Gitea.InMemory/Client.fs @@ -5,11 +5,11 @@ open Gitea.Declarative type private ServerState = { - Users : Map + Users : Map Repos : (User * Repo) list } - member this.WithUser (create : Gitea.CreateUserOption) : ServerState = + member this.WithUser (create : GiteaClient.CreateUserOption) : ServerState = let user = User create.Username match Map.tryFind user this.Users with @@ -27,7 +27,7 @@ type private ServerState = Repos = [] } -type private ServerMessage = | AddUser of Gitea.CreateUserOption * AsyncReplyChannel +type private ServerMessage = | AddUser of GiteaClient.CreateUserOption * AsyncReplyChannel type Server = private @@ -51,57 +51,18 @@ module Client = return! loop (state.WithUser user) mailbox } - let make () : Server * IGiteaClient = + let make () : Server * GiteaClient.IGiteaClient = let server = MailboxProcessor.Start (loop ServerState.Empty) let client = - { new IGiteaClient with - member _.AdminGetAllUsers (page, limit) = failwith "Not implemented" - - member _.AdminCreateUser createUserOption = - async { - let! () = server.PostAndAsyncReply (fun reply -> AddUser (createUserOption, reply)) - return Operations.createdUser createUserOption - } - |> Async.StartAsTask - - member _.AdminDeleteUser user = failwith "Not implemented" - - member _.AdminEditUser (user, editUserOption) = failwith "Not implemented" - - member _.AdminCreateRepo (user, createRepoOption) = failwith "Not implemented" - - member _.UserListRepos (user, page, count) = failwith "Not implemented" - - member _.RepoAddPushMirror (user, repo, createPushMirrorOption) = failwith "Not implemented" - - member _.RepoDeletePushMirror (user, repo, remoteName) = failwith "Not implemented" - - member _.RepoListPushMirrors (loginName, userName, page, count) = failwith "Not implemented" - - member _.RepoListBranchProtection (loginName, userName) = failwith "Not implemented" - - member _.RepoDeleteBranchProtection (user, repo, branch) = failwith "Not implemented" - - member _.RepoCreateBranchProtection (user, repo, createBranchProtectionOption) = - failwith "Not implemented" - - member _.RepoEditBranchProtection (user, repo, branch, editBranchProtectionOption) = - failwith "Not implemented" - - member _.RepoMigrate migrateRepoOptions = failwith "Not implemented" - - member _.RepoGet (user, repo) = failwith "Not implemented" - - member _.RepoDelete (user, repo) = failwith "Not implemented" - - member _.RepoEdit (user, repo, editRepoOption) = failwith "Not implemented" - - member _.RepoListCollaborators (loginName, userName, page, count) = failwith "Not implemented" - - member _.RepoAddCollaborator (user, repo, collaborator) = failwith "Not implemented" - - member _.RepoDeleteCollaborator (user, repo, collaborator) = failwith "Not implemented" + { GiteaClient.GiteaClientMock.Empty with + AdminCreateUser = + fun (createUserOption, _ct) -> + async { + let! () = server.PostAndAsyncReply (fun reply -> AddUser (createUserOption, reply)) + return Operations.createdUser createUserOption + } + |> Async.StartAsTask } Server server, client diff --git a/Gitea.InMemory/Domain.fs b/Gitea.InMemory/Domain.fs index bf111bc..e3c5799 100644 --- a/Gitea.InMemory/Domain.fs +++ b/Gitea.InMemory/Domain.fs @@ -21,108 +21,3 @@ module Types = type Repo = | GitHubMirror of Uri | NativeRepo of NativeRepo - -/// Allows us to use handy record-updating syntax. -/// (I have a considerable dislike of Moq and friends.) -type GiteaClientMock = - { - AdminGetAllUsers : int64 option * int64 option -> Gitea.User array Task - AdminCreateUser : Gitea.CreateUserOption -> Gitea.User Task - AdminDeleteUser : string -> unit Task - AdminEditUser : string * Gitea.EditUserOption -> Gitea.User Task - AdminCreateRepo : string * Gitea.CreateRepoOption -> Gitea.Repository Task - - UserListRepos : string * int64 option * int64 option -> Gitea.Repository array Task - - RepoAddPushMirror : string * string * Gitea.CreatePushMirrorOption -> Gitea.PushMirror Task - RepoDeletePushMirror : string * string * string -> unit Task - RepoListPushMirrors : string * string * int64 option * int64 option -> Gitea.PushMirror array Task - - RepoListBranchProtection : string * string -> Gitea.BranchProtection array Task - RepoDeleteBranchProtection : string * string * string -> unit Task - RepoCreateBranchProtection : string * string * Gitea.CreateBranchProtectionOption -> Gitea.BranchProtection Task - RepoEditBranchProtection : - string * string * string * Gitea.EditBranchProtectionOption -> Gitea.BranchProtection Task - - RepoMigrate : Gitea.MigrateRepoOptions -> Gitea.Repository Task - RepoGet : string * string -> Gitea.Repository Task - RepoDelete : string * string -> unit Task - RepoEdit : string * string * Gitea.EditRepoOption -> Gitea.Repository Task - - RepoListCollaborators : string * string * int64 option * int64 option -> Gitea.User array Task - RepoAddCollaborator : string * string * string -> unit Task - RepoDeleteCollaborator : string * string * string -> unit Task - } - - static member Unimplemented = - { - AdminGetAllUsers = fun _ -> failwith "Unimplemented" - AdminCreateUser = fun _ -> failwith "Unimplemented" - AdminDeleteUser = fun _ -> failwith "Unimplemented" - AdminEditUser = fun _ -> failwith "Unimplemented" - AdminCreateRepo = fun _ -> failwith "Unimplemented" - - UserListRepos = fun _ -> failwith "Unimplemented" - - RepoAddPushMirror = fun _ -> failwith "Unimplemented" - RepoDeletePushMirror = fun _ -> failwith "Unimplemented" - RepoListPushMirrors = fun _ -> failwith "Unimplemented" - - RepoListBranchProtection = fun _ -> failwith "Unimplemented" - RepoDeleteBranchProtection = fun _ -> failwith "Unimplemented" - RepoCreateBranchProtection = fun _ -> failwith "Unimplemented" - RepoEditBranchProtection = fun _ -> failwith "Unimplemented" - - RepoMigrate = fun _ -> failwith "Unimplemented" - RepoGet = fun _ -> failwith "Unimplemented" - RepoDelete = fun _ -> failwith "Unimplemented" - RepoEdit = fun _ -> failwith "Unimplemented" - - RepoListCollaborators = fun _ -> failwith "Unimplemented" - RepoAddCollaborator = fun _ -> failwith "Unimplemented" - RepoDeleteCollaborator = fun _ -> failwith "Unimplemented" - } - - interface IGiteaClient with - member this.AdminGetAllUsers (page, limit) = this.AdminGetAllUsers (page, limit) - member this.AdminCreateUser user = this.AdminCreateUser user - member this.AdminDeleteUser user = this.AdminDeleteUser user - member this.AdminEditUser (user, option) = this.AdminEditUser (user, option) - member this.AdminCreateRepo (user, option) = this.AdminCreateRepo (user, option) - - member this.UserListRepos (user, page, count) = this.UserListRepos (user, page, count) - - member this.RepoAddPushMirror (user, repo, options) = - this.RepoAddPushMirror (user, repo, options) - - member this.RepoListPushMirrors (loginName, userName, page, count) = - this.RepoListPushMirrors (loginName, userName, page, count) - - member this.RepoDeletePushMirror (loginName, userName, remoteName) = - this.RepoDeletePushMirror (loginName, userName, remoteName) - - member this.RepoListBranchProtection (login, user) = - this.RepoListBranchProtection (login, user) - - member this.RepoDeleteBranchProtection (user, repo, branch) = - this.RepoDeleteBranchProtection (user, repo, branch) - - member this.RepoCreateBranchProtection (user, repo, options) = - this.RepoCreateBranchProtection (user, repo, options) - - member this.RepoEditBranchProtection (user, repo, branch, edit) = - this.RepoEditBranchProtection (user, repo, branch, edit) - - member this.RepoMigrate options = this.RepoMigrate options - member this.RepoGet (user, repo) = this.RepoGet (user, repo) - member this.RepoDelete (user, repo) = this.RepoDelete (user, repo) - member this.RepoEdit (user, repo, options) = this.RepoEdit (user, repo, options) - - member this.RepoListCollaborators (login, user, page, count) = - this.RepoListCollaborators (login, user, page, count) - - member this.RepoAddCollaborator (user, repo, collaborator) = - this.RepoAddCollaborator (user, repo, collaborator) - - member this.RepoDeleteCollaborator (user, repo, collaborator) = - this.RepoDeleteCollaborator (user, repo, collaborator) diff --git a/Gitea.InMemory/Server.fs b/Gitea.InMemory/Server.fs index 08513c9..4b366c7 100644 --- a/Gitea.InMemory/Server.fs +++ b/Gitea.InMemory/Server.fs @@ -1,18 +1,33 @@ namespace Gitea.InMemory -open Gitea.Declarative +open System.Collections.Generic [] module Operations = - let createdUser (createUserOption : Gitea.CreateUserOption) : Gitea.User = - let result = Gitea.User () - result.Email <- createUserOption.Email - result.Restricted <- createUserOption.Restricted - // TODO: what is this username used for anyway - // result.LoginName <- createUserOption.Username - result.Visibility <- createUserOption.Visibility - result.Created <- createUserOption.CreatedAt - result.FullName <- createUserOption.FullName - result.LoginName <- createUserOption.LoginName + let createdUser (createUserOption : GiteaClient.CreateUserOption) : GiteaClient.User = + let result : GiteaClient.User = + { + AdditionalProperties = Dictionary () + Active = None + AvatarUrl = None + Created = None + Description = None + Email = Some createUserOption.Email + FollowersCount = None + FollowingCount = None + FullName = createUserOption.FullName + Id = None + IsAdmin = None + Language = None + LastLogin = None + Location = None + Login = None + LoginName = createUserOption.LoginName + ProhibitLogin = failwith "todo" + Restricted = createUserOption.Restricted + StarredReposCount = None + Visibility = createUserOption.Visibility + Website = None + } result diff --git a/README.md b/README.md index 23c147f..2f60165 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,8 @@ This is a small project to allow you to specify a [Gitea](https://github.com/go- * Pull request configuration (e.g. whether rebase-merges are allowed, etc) * Collaborators * Reconciliation of differences between configuration and reality in the above + * Note that deleting a line of configuration will generally simply take that property out of declarative management. + It does *not* return the configured property to its default value. Explicit is better than implicit. * Deletion of repositories, guarded by the `"deleted": true` configuration # Arguments @@ -31,7 +33,7 @@ See the [Demos file](./docs/demos.md). # Development -To upgrade the NuGet dependencies in the flake, run `nix build .#fetchDeps` and copy the resulting file into `nix/deps.nix`. +To upgrade the NuGet dependencies in the flake, run `nix build .#default.passthru.fetch-deps && ./result` and copy the resulting file into `nix/deps.nix`. ## Formatting