diff options
author | Daniel Baumann <daniel@debian.org> | 2024-11-20 06:17:50 +0100 |
---|---|---|
committer | Daniel Baumann <daniel@debian.org> | 2024-11-20 07:18:40 +0100 |
commit | 85e43976a325aa5dc37efddb2fff597d5b73f551 (patch) | |
tree | f5fe374162cdbcc5cc2c1a0c48636eb0acf3e6c5 | |
parent | Initial commit. (diff) | |
download | forgejo-api-85e43976a325aa5dc37efddb2fff597d5b73f551.tar.xz forgejo-api-85e43976a325aa5dc37efddb2fff597d5b73f551.zip |
Adding upstream version 0.4.1.
Signed-off-by: Daniel Baumann <daniel@debian.org>
-rw-r--r-- | .cargo_vcs_info.json | 6 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .woodpecker/check.yml | 13 | ||||
-rw-r--r-- | .woodpecker/integration.yml | 15 | ||||
-rw-r--r-- | Cargo.toml | 105 | ||||
-rw-r--r-- | Cargo.toml.orig | 28 | ||||
-rw-r--r-- | LICENSE-APACHE | 201 | ||||
-rw-r--r-- | LICENSE-MIT | 21 | ||||
-rw-r--r-- | README.md | 13 | ||||
-rw-r--r-- | src/generated/methods.rs | 8078 | ||||
-rw-r--r-- | src/generated/mod.rs | 2 | ||||
-rw-r--r-- | src/generated/structs.rs | 6487 | ||||
-rw-r--r-- | src/lib.rs | 437 | ||||
-rw-r--r-- | swagger.v1.json | 25101 | ||||
-rw-r--r-- | tests/admin.rs | 194 | ||||
-rw-r--r-- | tests/common/mod.rs | 17 | ||||
-rw-r--r-- | tests/organization.rs | 58 | ||||
-rw-r--r-- | tests/repo.rs | 495 | ||||
-rw-r--r-- | tests/user.rs | 237 |
19 files changed, 41510 insertions, 0 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json new file mode 100644 index 0000000..a0aeb03 --- /dev/null +++ b/.cargo_vcs_info.json @@ -0,0 +1,6 @@ +{ + "git": { + "sha1": "ecbc505270cabdbd34402c0c118cb35df53ff257" + }, + "path_in_vcs": "" +}
\ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..821a346 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/target +/test_repos diff --git a/.woodpecker/check.yml b/.woodpecker/check.yml new file mode 100644 index 0000000..20508ea --- /dev/null +++ b/.woodpecker/check.yml @@ -0,0 +1,13 @@ +when: + - event: manual + - event: pull_request +steps: + check: + image: rust + commands: + - cargo check + check-fmt: + image: rust + commands: + - rustup component add rustfmt + - cargo fmt --check diff --git a/.woodpecker/integration.yml b/.woodpecker/integration.yml new file mode 100644 index 0000000..8dd4e3e --- /dev/null +++ b/.woodpecker/integration.yml @@ -0,0 +1,15 @@ +when: + - event: manual +steps: + test: + image: rust + environment: + - "FORGEJO_API_CI_INSTANCE_URL=http://forgejo-testing:3000/" + - FORGEJO_API_CI_TOKEN=e4f301dffd4993a3389f601761c0103291e58d85 + commands: + - cargo test + +services: + forgejo-testing: + pull: true + image: code.cartoon-aa.xyz/cyborus/ci-forgejo:8.0.0 diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..4e90081 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,105 @@ +# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO +# +# When uploading crates to the registry Cargo will automatically +# "normalize" Cargo.toml files for maximal compatibility +# with all versions of Cargo and also rewrite `path` dependencies +# to registry (e.g., crates.io) dependencies. +# +# If you are reading this file be aware that the original Cargo.toml +# will likely look very different (and much more reasonable). +# See Cargo.toml.orig for the original contents. + +[package] +edition = "2021" +name = "forgejo-api" +version = "0.4.1" +build = false +autobins = false +autoexamples = false +autotests = false +autobenches = false +description = "Interface to Forgejo's Web API" +readme = "README.md" +license = "Apache-2.0 OR MIT" +repository = "https://codeberg.org/Cyborus/forgejo-api" + +[lib] +name = "forgejo_api" +path = "src/lib.rs" + +[[test]] +name = "admin" +path = "tests/admin.rs" + +[[test]] +name = "organization" +path = "tests/organization.rs" + +[[test]] +name = "repo" +path = "tests/repo.rs" + +[[test]] +name = "user" +path = "tests/user.rs" + +[dependencies.base64ct] +version = "1.6.0" + +[dependencies.bytes] +version = "1.5.0" + +[dependencies.reqwest] +version = "0.11.18" +features = [ + "json", + "multipart", +] + +[dependencies.serde] +version = "1.0.168" +features = ["derive"] + +[dependencies.serde_json] +version = "1.0.108" + +[dependencies.soft_assert] +version = "0.1.1" + +[dependencies.thiserror] +version = "1.0.43" + +[dependencies.time] +version = "0.3.26" +features = [ + "parsing", + "serde", + "formatting", +] + +[dependencies.tokio] +version = "1.29.1" +features = ["net"] + +[dependencies.url] +version = "2.4.0" +features = ["serde"] + +[dependencies.zeroize] +version = "1.7.0" + +[dev-dependencies.eyre] +version = "0.6.9" + +[dev-dependencies.reqwest] +version = "0.11.18" +features = ["cookies"] + +[dev-dependencies.tokio] +version = "1.29.1" +features = [ + "net", + "fs", + "rt", + "macros", +] diff --git a/Cargo.toml.orig b/Cargo.toml.orig new file mode 100644 index 0000000..b15a8d0 --- /dev/null +++ b/Cargo.toml.orig @@ -0,0 +1,28 @@ +workspace = { members = ["generator"] } +[package] +name = "forgejo-api" +version = "0.4.1" +edition = "2021" +license = "Apache-2.0 OR MIT" +repository = "https://codeberg.org/Cyborus/forgejo-api" +description = "Interface to Forgejo's Web API" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +reqwest = { version = "0.11.18", features = ["json", "multipart"] } +soft_assert = "0.1.1" +thiserror = "1.0.43" +tokio = { version = "1.29.1", features = ["net"] } +url = { version = "2.4.0", features = ["serde"] } +serde = { version = "1.0.168", features = ["derive"] } +time = { version = "0.3.26", features = ["parsing", "serde", "formatting"] } +serde_json = "1.0.108" +bytes = "1.5.0" +base64ct = "1.6.0" +zeroize = "1.7.0" + +[dev-dependencies] +eyre = "0.6.9" +reqwest = { version = "0.11.18", features = ["cookies"] } +tokio = { version = "1.29.1", features = ["net", "fs", "rt", "macros"] } diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 0000000..8aa2645 --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [year] [fullname] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c6e438e --- /dev/null +++ b/README.md @@ -0,0 +1,13 @@ +# forgejo-api + +Rust interface to Forgejo's Web API. + +# Licensing + +This project is licensed under either +[Apache License Version 2.0](LICENSE-APACHE) or [MIT License](LICENSE-MIT) +at your option. + +Unless you explicitly state otherwise, any contribution intentionally submitted +for inclusion in the work by you, as defined in the Apache-2.0 license, shall be +dual licensed as above, without any additional terms or conditions. diff --git a/src/generated/methods.rs b/src/generated/methods.rs new file mode 100644 index 0000000..2b23abf --- /dev/null +++ b/src/generated/methods.rs @@ -0,0 +1,8078 @@ +use super::structs::*; +use crate::ForgejoError; +use std::collections::BTreeMap; + +impl crate::Forgejo { + /// Returns the Repository actor for a repo + /// + /// - `repository-id`: repository ID of the repo + pub async fn activitypub_repository( + &self, + repository_id: u32, + ) -> Result<ActivityPub, ForgejoError> { + let request = self + .get(&format!("activitypub/repository-id/{repository_id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Send to the inbox + /// + /// - `repository-id`: repository ID of the repo + /// - `body`: See [`ForgeLike`] + pub async fn activitypub_repository_inbox( + &self, + repository_id: u32, + body: ForgeLike, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("activitypub/repository-id/{repository_id}/inbox")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns the Person actor for a user + /// + /// - `user-id`: user ID of the user + pub async fn activitypub_person(&self, user_id: u32) -> Result<ActivityPub, ForgejoError> { + let request = self + .get(&format!("activitypub/user-id/{user_id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Send to the inbox + /// + /// - `user-id`: user ID of the user + pub async fn activitypub_person_inbox(&self, user_id: u32) -> Result<(), ForgejoError> { + let request = self + .post(&format!("activitypub/user-id/{user_id}/inbox")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List cron tasks + /// + pub async fn admin_cron_list( + &self, + query: AdminCronListQuery, + ) -> Result<Vec<Cron>, ForgejoError> { + let request = self.get(&format!("admin/cron?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Run cron task + /// + /// - `task`: task to run + pub async fn admin_cron_run(&self, task: &str) -> Result<(), ForgejoError> { + let request = self.post(&format!("admin/cron/{task}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all emails + /// + pub async fn admin_get_all_emails( + &self, + query: AdminGetAllEmailsQuery, + ) -> Result<Vec<Email>, ForgejoError> { + let request = self.get(&format!("admin/emails?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search all emails + /// + pub async fn admin_search_emails( + &self, + query: AdminSearchEmailsQuery, + ) -> Result<Vec<Email>, ForgejoError> { + let request = self.get(&format!("admin/emails/search?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List system's webhooks + /// + pub async fn admin_list_hooks( + &self, + query: AdminListHooksQuery, + ) -> Result<Vec<Hook>, ForgejoError> { + let request = self.get(&format!("admin/hooks?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a hook + /// + /// - `body`: See [`CreateHookOption`] + pub async fn admin_create_hook(&self, body: CreateHookOption) -> Result<Hook, ForgejoError> { + let request = self.post("admin/hooks").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a hook + /// + /// - `id`: id of the hook to get + pub async fn admin_get_hook(&self, id: u64) -> Result<Hook, ForgejoError> { + let request = self.get(&format!("admin/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a hook + /// + /// - `id`: id of the hook to delete + pub async fn admin_delete_hook(&self, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("admin/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a hook + /// + /// - `id`: id of the hook to update + /// - `body`: See [`EditHookOption`] + pub async fn admin_edit_hook( + &self, + id: u64, + body: EditHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .patch(&format!("admin/hooks/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all organizations + /// + pub async fn admin_get_all_orgs( + &self, + query: AdminGetAllOrgsQuery, + ) -> Result<Vec<Organization>, ForgejoError> { + let request = self.get(&format!("admin/orgs?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an global actions runner registration token + pub async fn admin_get_runner_registration_token( + &self, + ) -> Result<RegistrationTokenHeaders, ForgejoError> { + let request = self.get("admin/runners/registration-token").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.headers().try_into()?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List unadopted repositories + /// + pub async fn admin_unadopted_list( + &self, + query: AdminUnadoptedListQuery, + ) -> Result<Vec<String>, ForgejoError> { + let request = self.get(&format!("admin/unadopted?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Adopt unadopted files as a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn admin_adopt_repository( + &self, + owner: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("admin/unadopted/{owner}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete unadopted files + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn admin_delete_unadopted_repository( + &self, + owner: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("admin/unadopted/{owner}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search users according filter conditions + /// + pub async fn admin_search_users( + &self, + query: AdminSearchUsersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self.get(&format!("admin/users?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a user + /// + /// - `body`: See [`CreateUserOption`] + pub async fn admin_create_user(&self, body: CreateUserOption) -> Result<User, ForgejoError> { + let request = self.post("admin/users").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a user + /// + /// - `username`: username of user to delete + pub async fn admin_delete_user( + &self, + username: &str, + query: AdminDeleteUserQuery, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("admin/users/{username}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit an existing user + /// + /// - `username`: username of user to edit + /// - `body`: See [`EditUserOption`] + pub async fn admin_edit_user( + &self, + username: &str, + body: EditUserOption, + ) -> Result<User, ForgejoError> { + let request = self + .patch(&format!("admin/users/{username}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a public key on behalf of a user + /// + /// - `username`: username of the user + /// - `key`: See [`CreateKeyOption`] + pub async fn admin_create_public_key( + &self, + username: &str, + key: CreateKeyOption, + ) -> Result<PublicKey, ForgejoError> { + let request = self + .post(&format!("admin/users/{username}/keys")) + .json(&key) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a user's public key + /// + /// - `username`: username of user + /// - `id`: id of the key to delete + pub async fn admin_delete_user_public_key( + &self, + username: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("admin/users/{username}/keys/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an organization + /// + /// - `username`: username of the user that will own the created organization + /// - `organization`: See [`CreateOrgOption`] + pub async fn admin_create_org( + &self, + username: &str, + organization: CreateOrgOption, + ) -> Result<Organization, ForgejoError> { + let request = self + .post(&format!("admin/users/{username}/orgs")) + .json(&organization) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Rename a user + /// + /// - `username`: existing username of user + /// - `body`: See [`RenameUserOption`] + pub async fn admin_rename_user( + &self, + username: &str, + body: RenameUserOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("admin/users/{username}/rename")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repository on behalf of a user + /// + /// - `username`: username of the user. This user will own the created repository + /// - `repository`: See [`CreateRepoOption`] + pub async fn admin_create_repo( + &self, + username: &str, + repository: CreateRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("admin/users/{username}/repos")) + .json(&repository) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns a list of all gitignore templates + pub async fn list_gitignores_templates(&self) -> Result<Vec<String>, ForgejoError> { + let request = self.get("gitignore/templates").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns information about a gitignore template + /// + /// - `name`: name of the template + pub async fn get_gitignore_template_info( + &self, + name: &str, + ) -> Result<GitignoreTemplateInfo, ForgejoError> { + let request = self.get(&format!("gitignore/templates/{name}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns a list of all label templates + pub async fn list_label_templates(&self) -> Result<Vec<String>, ForgejoError> { + let request = self.get("label/templates").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns all labels in a template + /// + /// - `name`: name of the template + pub async fn get_label_template_info( + &self, + name: &str, + ) -> Result<Vec<LabelTemplate>, ForgejoError> { + let request = self.get(&format!("label/templates/{name}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns a list of all license templates + pub async fn list_license_templates( + &self, + ) -> Result<Vec<LicensesTemplateListEntry>, ForgejoError> { + let request = self.get("licenses").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns information about a license template + /// + /// - `name`: name of the license + pub async fn get_license_template_info( + &self, + name: &str, + ) -> Result<LicenseTemplateInfo, ForgejoError> { + let request = self.get(&format!("licenses/{name}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Render a markdown document as HTML + /// + /// - `body`: See [`MarkdownOption`] + pub async fn render_markdown(&self, body: MarkdownOption) -> Result<String, ForgejoError> { + let request = self.post("markdown").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Render raw markdown as HTML + /// + /// - `body`: Request body to render + + /// See [`String`] + pub async fn render_markdown_raw(&self, body: String) -> Result<String, ForgejoError> { + let request = self.post("markdown/raw").body(body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Render a markup document as HTML + /// + /// - `body`: See [`MarkupOption`] + pub async fn render_markup(&self, body: MarkupOption) -> Result<String, ForgejoError> { + let request = self.post("markup").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns the nodeinfo of the Forgejo application + pub async fn get_node_info(&self) -> Result<NodeInfo, ForgejoError> { + let request = self.get("nodeinfo").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List users's notification threads + /// + pub async fn notify_get_list( + &self, + query: NotifyGetListQuery, + ) -> Result<Vec<NotificationThread>, ForgejoError> { + let request = self.get(&format!("notifications?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Mark notification threads as read, pinned or unread + /// + pub async fn notify_read_list( + &self, + query: NotifyReadListQuery, + ) -> Result<Vec<NotificationThread>, ForgejoError> { + let request = self.put(&format!("notifications?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 205 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if unread notifications exist + pub async fn notify_new_available(&self) -> Result<NotificationCount, ForgejoError> { + let request = self.get("notifications/new").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get notification thread by ID + /// + /// - `id`: id of notification thread + pub async fn notify_get_thread(&self, id: &str) -> Result<NotificationThread, ForgejoError> { + let request = self.get(&format!("notifications/threads/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Mark notification thread as read by ID + /// + /// - `id`: id of notification thread + pub async fn notify_read_thread( + &self, + id: &str, + query: NotifyReadThreadQuery, + ) -> Result<NotificationThread, ForgejoError> { + let request = self + .patch(&format!("notifications/threads/{id}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 205 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repository in an organization + /// + /// - `org`: name of organization + /// - `body`: See [`CreateRepoOption`] + pub async fn create_org_repo_deprecated( + &self, + org: &str, + body: CreateRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self.post(&format!("org/{org}/repos")).json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get list of organizations + /// + pub async fn org_get_all( + &self, + query: OrgGetAllQuery, + ) -> Result<Vec<Organization>, ForgejoError> { + let request = self.get(&format!("orgs?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an organization + /// + /// - `organization`: See [`CreateOrgOption`] + pub async fn org_create( + &self, + organization: CreateOrgOption, + ) -> Result<Organization, ForgejoError> { + let request = self.post("orgs").json(&organization).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an organization + /// + /// - `org`: name of the organization to get + pub async fn org_get(&self, org: &str) -> Result<Organization, ForgejoError> { + let request = self.get(&format!("orgs/{org}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete an organization + /// + /// - `org`: organization that is to be deleted + pub async fn org_delete(&self, org: &str) -> Result<(), ForgejoError> { + let request = self.delete(&format!("orgs/{org}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit an organization + /// + /// - `org`: name of the organization to edit + /// - `body`: See [`EditOrgOption`] + pub async fn org_edit( + &self, + org: &str, + body: EditOrgOption, + ) -> Result<Organization, ForgejoError> { + let request = self.patch(&format!("orgs/{org}")).json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an organization's actions runner registration token + /// + /// - `org`: name of the organization + pub async fn org_get_runner_registration_token( + &self, + org: &str, + ) -> Result<RegistrationTokenHeaders, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/actions/runners/registration-token")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.headers().try_into()?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's actions secrets + /// + /// - `org`: name of the organization + pub async fn org_list_actions_secrets( + &self, + org: &str, + query: OrgListActionsSecretsQuery, + ) -> Result<Vec<Secret>, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/actions/secrets?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create or Update a secret value in an organization + /// + /// - `org`: name of organization + /// - `secretname`: name of the secret + /// - `body`: See [`CreateOrUpdateSecretOption`] + pub async fn update_org_secret( + &self, + org: &str, + secretname: &str, + body: CreateOrUpdateSecretOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("orgs/{org}/actions/secrets/{secretname}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a secret in an organization + /// + /// - `org`: name of organization + /// - `secretname`: name of the secret + pub async fn delete_org_secret(&self, org: &str, secretname: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("orgs/{org}/actions/secrets/{secretname}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an org-level variables list + /// + /// - `org`: name of the organization + pub async fn get_org_variables_list( + &self, + org: &str, + query: GetOrgVariablesListQuery, + ) -> Result<Vec<ActionVariable>, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/actions/variables?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an org-level variable + /// + /// - `org`: name of the organization + /// - `variablename`: name of the variable + pub async fn get_org_variable( + &self, + org: &str, + variablename: &str, + ) -> Result<ActionVariable, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/actions/variables/{variablename}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update an org-level variable + /// + /// - `org`: name of the organization + /// - `variablename`: name of the variable + /// - `body`: See [`UpdateVariableOption`] + pub async fn update_org_variable( + &self, + org: &str, + variablename: &str, + body: UpdateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("orgs/{org}/actions/variables/{variablename}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an org-level variable + /// + /// - `org`: name of the organization + /// - `variablename`: name of the variable + /// - `body`: See [`CreateVariableOption`] + pub async fn create_org_variable( + &self, + org: &str, + variablename: &str, + body: CreateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("orgs/{org}/actions/variables/{variablename}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete an org-level variable + /// + /// - `org`: name of the organization + /// - `variablename`: name of the variable + pub async fn delete_org_variable( + &self, + org: &str, + variablename: &str, + ) -> Result<Option<ActionVariable>, ForgejoError> { + let request = self + .delete(&format!("orgs/{org}/actions/variables/{variablename}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(Some(response.json().await?)), + 201 => Ok(None), + 204 => Ok(None), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's activity feeds + /// + /// - `org`: name of the org + pub async fn org_list_activity_feeds( + &self, + org: &str, + query: OrgListActivityFeedsQuery, + ) -> Result<Vec<Activity>, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/activities/feeds?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update Avatar + /// + /// - `org`: name of the organization + /// - `body`: See [`UpdateUserAvatarOption`] + pub async fn org_update_avatar( + &self, + org: &str, + body: UpdateUserAvatarOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("orgs/{org}/avatar")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete Avatar + /// + /// - `org`: name of the organization + pub async fn org_delete_avatar(&self, org: &str) -> Result<(), ForgejoError> { + let request = self.delete(&format!("orgs/{org}/avatar")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Blocks a user from the organization + /// + /// - `org`: name of the org + /// - `username`: username of the user + pub async fn org_block_user(&self, org: &str, username: &str) -> Result<(), ForgejoError> { + let request = self.put(&format!("orgs/{org}/block/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's webhooks + /// + /// - `org`: name of the organization + pub async fn org_list_hooks( + &self, + org: &str, + query: OrgListHooksQuery, + ) -> Result<Vec<Hook>, ForgejoError> { + let request = self.get(&format!("orgs/{org}/hooks?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a hook + /// + /// - `org`: name of the organization + /// - `body`: See [`CreateHookOption`] + pub async fn org_create_hook( + &self, + org: &str, + body: CreateHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .post(&format!("orgs/{org}/hooks")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a hook + /// + /// - `org`: name of the organization + /// - `id`: id of the hook to get + pub async fn org_get_hook(&self, org: &str, id: u64) -> Result<Hook, ForgejoError> { + let request = self.get(&format!("orgs/{org}/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a hook + /// + /// - `org`: name of the organization + /// - `id`: id of the hook to delete + pub async fn org_delete_hook(&self, org: &str, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("orgs/{org}/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a hook + /// + /// - `org`: name of the organization + /// - `id`: id of the hook to update + /// - `body`: See [`EditHookOption`] + pub async fn org_edit_hook( + &self, + org: &str, + id: u64, + body: EditHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .patch(&format!("orgs/{org}/hooks/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's labels + /// + /// - `org`: name of the organization + pub async fn org_list_labels( + &self, + org: &str, + query: OrgListLabelsQuery, + ) -> Result<Vec<Label>, ForgejoError> { + let request = self.get(&format!("orgs/{org}/labels?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a label for an organization + /// + /// - `org`: name of the organization + /// - `body`: See [`CreateLabelOption`] + pub async fn org_create_label( + &self, + org: &str, + body: CreateLabelOption, + ) -> Result<Label, ForgejoError> { + let request = self + .post(&format!("orgs/{org}/labels")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a single label + /// + /// - `org`: name of the organization + /// - `id`: id of the label to get + pub async fn org_get_label(&self, org: &str, id: u64) -> Result<Label, ForgejoError> { + let request = self.get(&format!("orgs/{org}/labels/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a label + /// + /// - `org`: name of the organization + /// - `id`: id of the label to delete + pub async fn org_delete_label(&self, org: &str, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("orgs/{org}/labels/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a label + /// + /// - `org`: name of the organization + /// - `id`: id of the label to edit + /// - `body`: See [`EditLabelOption`] + pub async fn org_edit_label( + &self, + org: &str, + id: u64, + body: EditLabelOption, + ) -> Result<Label, ForgejoError> { + let request = self + .patch(&format!("orgs/{org}/labels/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the organization's blocked users + /// + /// - `org`: name of the org + pub async fn org_list_blocked_users( + &self, + org: &str, + query: OrgListBlockedUsersQuery, + ) -> Result<Vec<BlockedUser>, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/list_blocked?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's members + /// + /// - `org`: name of the organization + pub async fn org_list_members( + &self, + org: &str, + query: OrgListMembersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self.get(&format!("orgs/{org}/members?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a user is a member of an organization + /// + /// - `org`: name of the organization + /// - `username`: username of the user + pub async fn org_is_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> { + let request = self + .get(&format!("orgs/{org}/members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a member from an organization + /// + /// - `org`: name of the organization + /// - `username`: username of the user + pub async fn org_delete_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("orgs/{org}/members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's public members + /// + /// - `org`: name of the organization + pub async fn org_list_public_members( + &self, + org: &str, + query: OrgListPublicMembersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/public_members?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a user is a public member of an organization + /// + /// - `org`: name of the organization + /// - `username`: username of the user + pub async fn org_is_public_member( + &self, + org: &str, + username: &str, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!("orgs/{org}/public_members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Publicize a user's membership + /// + /// - `org`: name of the organization + /// - `username`: username of the user + pub async fn org_publicize_member( + &self, + org: &str, + username: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("orgs/{org}/public_members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Conceal a user's membership + /// + /// - `org`: name of the organization + /// - `username`: username of the user + pub async fn org_conceal_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("orgs/{org}/public_members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's repos + /// + /// - `org`: name of the organization + pub async fn org_list_repos( + &self, + org: &str, + query: OrgListReposQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self.get(&format!("orgs/{org}/repos?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repository in an organization + /// + /// - `org`: name of organization + /// - `body`: See [`CreateRepoOption`] + pub async fn create_org_repo( + &self, + org: &str, + body: CreateRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("orgs/{org}/repos")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an organization's teams + /// + /// - `org`: name of the organization + pub async fn org_list_teams( + &self, + org: &str, + query: OrgListTeamsQuery, + ) -> Result<Vec<Team>, ForgejoError> { + let request = self.get(&format!("orgs/{org}/teams?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a team + /// + /// - `org`: name of the organization + /// - `body`: See [`CreateTeamOption`] + pub async fn org_create_team( + &self, + org: &str, + body: CreateTeamOption, + ) -> Result<Team, ForgejoError> { + let request = self + .post(&format!("orgs/{org}/teams")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search for teams within an organization + /// + /// - `org`: name of the organization + pub async fn team_search( + &self, + org: &str, + query: TeamSearchQuery, + ) -> Result<TeamSearchResponse, ForgejoError> { + let request = self + .get(&format!("orgs/{org}/teams/search?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unblock a user from the organization + /// + /// - `org`: name of the org + /// - `username`: username of the user + pub async fn org_unblock_user(&self, org: &str, username: &str) -> Result<(), ForgejoError> { + let request = self + .put(&format!("orgs/{org}/unblock/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets all packages of an owner + /// + /// - `owner`: owner of the packages + pub async fn list_packages( + &self, + owner: &str, + query: ListPackagesQuery, + ) -> Result<Vec<Package>, ForgejoError> { + let request = self.get(&format!("packages/{owner}?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets a package + /// + /// - `owner`: owner of the package + /// - `type`: type of the package + /// - `name`: name of the package + /// - `version`: version of the package + pub async fn get_package( + &self, + owner: &str, + r#type: &str, + name: &str, + version: &str, + ) -> Result<Package, ForgejoError> { + let request = self + .get(&format!("packages/{owner}/{type}/{name}/{version}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a package + /// + /// - `owner`: owner of the package + /// - `type`: type of the package + /// - `name`: name of the package + /// - `version`: version of the package + pub async fn delete_package( + &self, + owner: &str, + r#type: &str, + name: &str, + version: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("packages/{owner}/{type}/{name}/{version}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets all files of a package + /// + /// - `owner`: owner of the package + /// - `type`: type of the package + /// - `name`: name of the package + /// - `version`: version of the package + pub async fn list_package_files( + &self, + owner: &str, + r#type: &str, + name: &str, + version: &str, + ) -> Result<Vec<PackageFile>, ForgejoError> { + let request = self + .get(&format!("packages/{owner}/{type}/{name}/{version}/files")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search for issues across the repositories that the user has access to + /// + pub async fn issue_search_issues( + &self, + query: IssueSearchIssuesQuery, + ) -> Result<Vec<Issue>, ForgejoError> { + let request = self.get(&format!("repos/issues/search?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Migrate a remote git repository + /// + /// - `body`: See [`MigrateRepoOptions`] + pub async fn repo_migrate(&self, body: MigrateRepoOptions) -> Result<Repository, ForgejoError> { + let request = self.post("repos/migrate").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search for repositories + /// + pub async fn repo_search(&self, query: RepoSearchQuery) -> Result<SearchResults, ForgejoError> { + let request = self.get(&format!("repos/search?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get(&self, owner: &str, repo: &str) -> Result<Repository, ForgejoError> { + let request = self.get(&format!("repos/{owner}/{repo}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a repository + /// + /// - `owner`: owner of the repo to delete + /// - `repo`: name of the repo to delete + pub async fn repo_delete(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self.delete(&format!("repos/{owner}/{repo}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a repository's properties. Only fields that are set will be changed. + /// + /// - `owner`: owner of the repo to edit + /// - `repo`: name of the repo to edit + /// - `body`: Properties of a repo that you can edit + + /// See [`EditRepoOption`] + pub async fn repo_edit( + &self, + owner: &str, + repo: &str, + body: EditRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an repo's actions secrets + /// + /// - `owner`: owner of the repository + /// - `repo`: name of the repository + pub async fn repo_list_actions_secrets( + &self, + owner: &str, + repo: &str, + query: RepoListActionsSecretsQuery, + ) -> Result<Vec<Secret>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/actions/secrets?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create or Update a secret value in a repository + /// + /// - `owner`: owner of the repository + /// - `repo`: name of the repository + /// - `secretname`: name of the secret + /// - `body`: See [`CreateOrUpdateSecretOption`] + pub async fn update_repo_secret( + &self, + owner: &str, + repo: &str, + secretname: &str, + body: CreateOrUpdateSecretOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!( + "repos/{owner}/{repo}/actions/secrets/{secretname}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a secret in a repository + /// + /// - `owner`: owner of the repository + /// - `repo`: name of the repository + /// - `secretname`: name of the secret + pub async fn delete_repo_secret( + &self, + owner: &str, + repo: &str, + secretname: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/actions/secrets/{secretname}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's action tasks + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn list_action_tasks( + &self, + owner: &str, + repo: &str, + query: ListActionTasksQuery, + ) -> Result<ActionTaskResponse, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/actions/tasks?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get repo-level variables list + /// + /// - `owner`: name of the owner + /// - `repo`: name of the repository + pub async fn get_repo_variables_list( + &self, + owner: &str, + repo: &str, + query: GetRepoVariablesListQuery, + ) -> Result<Vec<ActionVariable>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/actions/variables?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a repo-level variable + /// + /// - `owner`: name of the owner + /// - `repo`: name of the repository + /// - `variablename`: name of the variable + pub async fn get_repo_variable( + &self, + owner: &str, + repo: &str, + variablename: &str, + ) -> Result<ActionVariable, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/actions/variables/{variablename}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a repo-level variable + /// + /// - `owner`: name of the owner + /// - `repo`: name of the repository + /// - `variablename`: name of the variable + /// - `body`: See [`UpdateVariableOption`] + pub async fn update_repo_variable( + &self, + owner: &str, + repo: &str, + variablename: &str, + body: UpdateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!( + "repos/{owner}/{repo}/actions/variables/{variablename}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repo-level variable + /// + /// - `owner`: name of the owner + /// - `repo`: name of the repository + /// - `variablename`: name of the variable + /// - `body`: See [`CreateVariableOption`] + pub async fn create_repo_variable( + &self, + owner: &str, + repo: &str, + variablename: &str, + body: CreateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/actions/variables/{variablename}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a repo-level variable + /// + /// - `owner`: name of the owner + /// - `repo`: name of the repository + /// - `variablename`: name of the variable + pub async fn delete_repo_variable( + &self, + owner: &str, + repo: &str, + variablename: &str, + ) -> Result<Option<ActionVariable>, ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/actions/variables/{variablename}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(Some(response.json().await?)), + 201 => Ok(None), + 204 => Ok(None), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Dispatches a workflow + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `workflowname`: name of the workflow + /// - `body`: See [`DispatchWorkflowOption`] + pub async fn dispatch_workflow( + &self, + owner: &str, + repo: &str, + workflowname: &str, + body: DispatchWorkflowOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/actions/workflows/{workflowname}/dispatches" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's activity feeds + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_activity_feeds( + &self, + owner: &str, + repo: &str, + query: RepoListActivityFeedsQuery, + ) -> Result<Vec<Activity>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/activities/feeds?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an archive of a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `archive`: the git reference for download with attached archive format (e.g. master.zip) + pub async fn repo_get_archive( + &self, + owner: &str, + repo: &str, + archive: &str, + ) -> Result<Vec<u8>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/archive/{archive}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.bytes().await?[..].to_vec()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Return all users that have write access and can be assigned to issues + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_assignees( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/assignees")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update avatar + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`UpdateRepoAvatarOption`] + pub async fn repo_update_avatar( + &self, + owner: &str, + repo: &str, + body: UpdateRepoAvatarOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/avatar")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete avatar + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_delete_avatar(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/avatar")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List branch protections for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_branch_protection( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<BranchProtection>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/branch_protections")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a branch protections for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateBranchProtectionOption`] + pub async fn repo_create_branch_protection( + &self, + owner: &str, + repo: &str, + body: CreateBranchProtectionOption, + ) -> Result<BranchProtection, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/branch_protections")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a specific branch protection for the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `name`: name of protected branch + pub async fn repo_get_branch_protection( + &self, + owner: &str, + repo: &str, + name: &str, + ) -> Result<BranchProtection, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/branch_protections/{name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a specific branch protection for the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `name`: name of protected branch + pub async fn repo_delete_branch_protection( + &self, + owner: &str, + repo: &str, + name: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/branch_protections/{name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a branch protections for a repository. Only fields that are set will be changed + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `name`: name of protected branch + /// - `body`: See [`EditBranchProtectionOption`] + pub async fn repo_edit_branch_protection( + &self, + owner: &str, + repo: &str, + name: &str, + body: EditBranchProtectionOption, + ) -> Result<BranchProtection, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/branch_protections/{name}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's branches + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_branches( + &self, + owner: &str, + repo: &str, + query: RepoListBranchesQuery, + ) -> Result<Vec<Branch>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/branches?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a branch + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateBranchRepoOption`] + pub async fn repo_create_branch( + &self, + owner: &str, + repo: &str, + body: CreateBranchRepoOption, + ) -> Result<Branch, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/branches")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Retrieve a specific branch from a repository, including its effective branch protection + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `branch`: branch to get + pub async fn repo_get_branch( + &self, + owner: &str, + repo: &str, + branch: &str, + ) -> Result<Branch, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/branches/{branch}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a specific branch from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `branch`: branch to delete + pub async fn repo_delete_branch( + &self, + owner: &str, + repo: &str, + branch: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/branches/{branch}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's collaborators + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_collaborators( + &self, + owner: &str, + repo: &str, + query: RepoListCollaboratorsQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/collaborators?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a user is a collaborator of a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `collaborator`: username of the collaborator + pub async fn repo_check_collaborator( + &self, + owner: &str, + repo: &str, + collaborator: &str, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/collaborators/{collaborator}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a collaborator to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `collaborator`: username of the collaborator to add + /// - `body`: See [`AddCollaboratorOption`] + pub async fn repo_add_collaborator( + &self, + owner: &str, + repo: &str, + collaborator: &str, + body: AddCollaboratorOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!( + "repos/{owner}/{repo}/collaborators/{collaborator}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a collaborator from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `collaborator`: username of the collaborator to delete + pub async fn repo_delete_collaborator( + &self, + owner: &str, + repo: &str, + collaborator: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/collaborators/{collaborator}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get repository permissions for a user + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `collaborator`: username of the collaborator + pub async fn repo_get_repo_permissions( + &self, + owner: &str, + repo: &str, + collaborator: &str, + ) -> Result<RepoCollaboratorPermission, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/collaborators/{collaborator}/permission" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a list of all commits from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_all_commits( + &self, + owner: &str, + repo: &str, + query: RepoGetAllCommitsQuery, + ) -> Result<(CommitListHeaders, Vec<Commit>), ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/commits?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok((response.headers().try_into()?, response.json().await?)), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a commit's combined status, by branch/tag/commit reference + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `ref`: name of branch/tag/commit + pub async fn repo_get_combined_status_by_ref( + &self, + owner: &str, + repo: &str, + r#ref: &str, + query: RepoGetCombinedStatusByRefQuery, + ) -> Result<CombinedStatus, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/commits/{ref}/status?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a commit's statuses, by branch/tag/commit reference + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `ref`: name of branch/tag/commit + pub async fn repo_list_statuses_by_ref( + &self, + owner: &str, + repo: &str, + r#ref: &str, + query: RepoListStatusesByRefQuery, + ) -> Result<Vec<CommitStatus>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/commits/{ref}/statuses?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get the pull request of the commit + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: SHA of the commit to get + pub async fn repo_get_commit_pull_request( + &self, + owner: &str, + repo: &str, + sha: &str, + ) -> Result<PullRequest, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/commits/{sha}/pull")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get commit comparison information + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `basehead`: compare two branches or commits + pub async fn repo_compare_diff( + &self, + owner: &str, + repo: &str, + basehead: &str, + ) -> Result<Compare, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/compare/{basehead}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the metadata of all the entries of the root dir + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_contents_list( + &self, + owner: &str, + repo: &str, + query: RepoGetContentsListQuery, + ) -> Result<Vec<ContentsResponse>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/contents?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Modify multiple files in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`ChangeFilesOptions`] + pub async fn repo_change_files( + &self, + owner: &str, + repo: &str, + body: ChangeFilesOptions, + ) -> Result<FilesResponse, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/contents")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: path of the dir, file, symlink or submodule in the repo + pub async fn repo_get_contents( + &self, + owner: &str, + repo: &str, + filepath: &str, + query: RepoGetContentsQuery, + ) -> Result<ContentsResponse, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/contents/{filepath}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a file in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: path of the file to update + /// - `body`: See [`UpdateFileOptions`] + pub async fn repo_update_file( + &self, + owner: &str, + repo: &str, + filepath: &str, + body: UpdateFileOptions, + ) -> Result<FileResponse, ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/contents/{filepath}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a file in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: path of the file to create + /// - `body`: See [`CreateFileOptions`] + pub async fn repo_create_file( + &self, + owner: &str, + repo: &str, + filepath: &str, + body: CreateFileOptions, + ) -> Result<FileResponse, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/contents/{filepath}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a file in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: path of the file to delete + /// - `body`: See [`DeleteFileOptions`] + pub async fn repo_delete_file( + &self, + owner: &str, + repo: &str, + filepath: &str, + body: DeleteFileOptions, + ) -> Result<FileDeleteResponse, ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/contents/{filepath}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Apply diff patch to repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`UpdateFileOptions`] + pub async fn repo_apply_diff_patch( + &self, + owner: &str, + repo: &str, + body: UpdateFileOptions, + ) -> Result<FileResponse, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/diffpatch")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get the EditorConfig definitions of a file in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: filepath of file to get + pub async fn repo_get_editor_config( + &self, + owner: &str, + repo: &str, + filepath: &str, + query: RepoGetEditorConfigQuery, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/editorconfig/{filepath}?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's flags + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_flags( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<String>, ForgejoError> { + let request = self.get(&format!("repos/{owner}/{repo}/flags")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Replace all flags of a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`ReplaceFlagsOption`] + pub async fn repo_replace_all_flags( + &self, + owner: &str, + repo: &str, + body: ReplaceFlagsOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/flags")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove all flags from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_delete_all_flags(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/flags")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a repository has a given flag + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `flag`: name of the flag + pub async fn repo_check_flag( + &self, + owner: &str, + repo: &str, + flag: &str, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/flags/{flag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a flag to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `flag`: name of the flag + pub async fn repo_add_flag( + &self, + owner: &str, + repo: &str, + flag: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/flags/{flag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a flag from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `flag`: name of the flag + pub async fn repo_delete_flag( + &self, + owner: &str, + repo: &str, + flag: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/flags/{flag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's forks + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn list_forks( + &self, + owner: &str, + repo: &str, + query: ListForksQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/forks?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Fork a repository + /// + /// - `owner`: owner of the repo to fork + /// - `repo`: name of the repo to fork + /// - `body`: See [`CreateForkOption`] + pub async fn create_fork( + &self, + owner: &str, + repo: &str, + body: CreateForkOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/forks")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 202 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the blob of a repository. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: sha of the commit + pub async fn get_blob( + &self, + owner: &str, + repo: &str, + sha: &str, + ) -> Result<GitBlobResponse, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/blobs/{sha}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a single commit from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: a git ref or commit sha + pub async fn repo_get_single_commit( + &self, + owner: &str, + repo: &str, + sha: &str, + query: RepoGetSingleCommitQuery, + ) -> Result<Commit, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/commits/{sha}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a commit's diff or patch + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: SHA of the commit to get + /// - `diffType`: whether the output is diff or patch + pub async fn repo_download_commit_diff_or_patch( + &self, + owner: &str, + repo: &str, + sha: &str, + diff_type: &str, + ) -> Result<String, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/git/commits/{sha}.{diff_type}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a note corresponding to a single commit from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: a git ref or commit sha + pub async fn repo_get_note( + &self, + owner: &str, + repo: &str, + sha: &str, + query: RepoGetNoteQuery, + ) -> Result<Note, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/notes/{sha}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get specified ref or filtered repository's refs + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_all_git_refs( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<Reference>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/refs")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get specified ref or filtered repository's refs + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `ref`: part or full name of the ref + pub async fn repo_list_git_refs( + &self, + owner: &str, + repo: &str, + r#ref: &str, + ) -> Result<Vec<Reference>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/refs/{ref}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the tag object of an annotated tag (not lightweight tags) + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags. + pub async fn get_annotated_tag( + &self, + owner: &str, + repo: &str, + sha: &str, + ) -> Result<AnnotatedTag, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/tags/{sha}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the tree of a repository. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: sha of the commit + pub async fn get_tree( + &self, + owner: &str, + repo: &str, + sha: &str, + query: GetTreeQuery, + ) -> Result<GitTreeResponse, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/git/trees/{sha}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the hooks in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_hooks( + &self, + owner: &str, + repo: &str, + query: RepoListHooksQuery, + ) -> Result<Vec<Hook>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/hooks?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a hook + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateHookOption`] + pub async fn repo_create_hook( + &self, + owner: &str, + repo: &str, + body: CreateHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/hooks")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the Git hooks in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_git_hooks( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<GitHook>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/hooks/git")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a Git hook + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to get + pub async fn repo_get_git_hook( + &self, + owner: &str, + repo: &str, + id: &str, + ) -> Result<GitHook, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/hooks/git/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a Git hook in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to get + pub async fn repo_delete_git_hook( + &self, + owner: &str, + repo: &str, + id: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/hooks/git/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a Git hook in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to get + /// - `body`: See [`EditGitHookOption`] + pub async fn repo_edit_git_hook( + &self, + owner: &str, + repo: &str, + id: &str, + body: EditGitHookOption, + ) -> Result<GitHook, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/hooks/git/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a hook + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to get + pub async fn repo_get_hook( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Hook, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/hooks/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a hook in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to delete + pub async fn repo_delete_hook( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/hooks/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a hook in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: index of the hook + /// - `body`: See [`EditHookOption`] + pub async fn repo_edit_hook( + &self, + owner: &str, + repo: &str, + id: u64, + body: EditHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/hooks/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Test a push webhook + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the hook to test + pub async fn repo_test_hook( + &self, + owner: &str, + repo: &str, + id: u64, + query: RepoTestHookQuery, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/hooks/{id}/tests?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns the issue config for a repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_issue_config( + &self, + owner: &str, + repo: &str, + ) -> Result<IssueConfig, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issue_config")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns the validation information for a issue config + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_validate_issue_config( + &self, + owner: &str, + repo: &str, + ) -> Result<IssueConfigValidation, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issue_config/validate")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get available issue templates for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_issue_templates( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<IssueTemplate>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issue_templates")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's issues + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn issue_list_issues( + &self, + owner: &str, + repo: &str, + query: IssueListIssuesQuery, + ) -> Result<Vec<Issue>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an issue. If using deadline only the date will be taken into account, and time of day ignored. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateIssueOption`] + pub async fn issue_create_issue( + &self, + owner: &str, + repo: &str, + body: CreateIssueOption, + ) -> Result<Issue, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all comments in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn issue_get_repo_comments( + &self, + owner: &str, + repo: &str, + query: IssueGetRepoCommentsQuery, + ) -> Result<Vec<Comment>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/comments?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + pub async fn issue_get_comment( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Option<Comment>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/comments/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(Some(response.json().await?)), + 204 => Ok(None), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of comment to delete + pub async fn issue_delete_comment( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/comments/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment to edit + /// - `body`: See [`EditIssueCommentOption`] + pub async fn issue_edit_comment( + &self, + owner: &str, + repo: &str, + id: u64, + body: EditIssueCommentOption, + ) -> Result<Option<Comment>, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/issues/comments/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(Some(response.json().await?)), + 204 => Ok(None), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List comment's attachments + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + pub async fn issue_list_issue_comment_attachments( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Vec<Attachment>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/comments/{id}/assets")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a comment attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + /// - `attachment`: attachment to upload + pub async fn issue_create_issue_comment_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment: Vec<u8>, + query: IssueCreateIssueCommentAttachmentQuery, + ) -> Result<Attachment, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/assets?{query}" + )) + .multipart( + reqwest::multipart::Form::new().part( + "attachment", + reqwest::multipart::Part::bytes(attachment) + .file_name("file") + .mime_str("*/*") + .unwrap(), + ), + ) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a comment attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + /// - `attachment_id`: id of the attachment to get + pub async fn issue_get_issue_comment_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + ) -> Result<Attachment, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a comment attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + /// - `attachment_id`: id of the attachment to delete + pub async fn issue_delete_issue_comment_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a comment attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment + /// - `attachment_id`: id of the attachment to edit + /// - `body`: See [`EditAttachmentOptions`] + pub async fn issue_edit_issue_comment_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + body: EditAttachmentOptions, + ) -> Result<Attachment, ForgejoError> { + let request = self + .patch(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a list of reactions from a comment of an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment to edit + pub async fn issue_get_comment_reactions( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Vec<Reaction>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/reactions" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a reaction to a comment of an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment to edit + /// - `content`: See [`EditReactionOption`] + pub async fn issue_post_comment_reaction( + &self, + owner: &str, + repo: &str, + id: u64, + content: EditReactionOption, + ) -> Result<Reaction, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/reactions" + )) + .json(&content) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a reaction from a comment of an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the comment to edit + /// - `content`: See [`EditReactionOption`] + pub async fn issue_delete_comment_reaction( + &self, + owner: &str, + repo: &str, + id: u64, + content: EditReactionOption, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/comments/{id}/reactions" + )) + .json(&content) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's pinned issues + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_pinned_issues( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<Issue>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/pinned")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to get + pub async fn issue_get_issue( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<Issue, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/{index}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of issue to delete + pub async fn issue_delete( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit an issue. If using deadline only the date will be taken into account, and time of day ignored. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to edit + /// - `body`: See [`EditIssueOption`] + pub async fn issue_edit_issue( + &self, + owner: &str, + repo: &str, + index: u64, + body: EditIssueOption, + ) -> Result<Issue, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/issues/{index}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List issue's attachments + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_list_issue_attachments( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<Vec<Attachment>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/{index}/assets")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an issue attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `attachment`: attachment to upload + pub async fn issue_create_issue_attachment( + &self, + owner: &str, + repo: &str, + index: u64, + attachment: Vec<u8>, + query: IssueCreateIssueAttachmentQuery, + ) -> Result<Attachment, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/issues/{index}/assets?{query}" + )) + .multipart( + reqwest::multipart::Form::new().part( + "attachment", + reqwest::multipart::Part::bytes(attachment) + .file_name("file") + .mime_str("*/*") + .unwrap(), + ), + ) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an issue attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `attachment_id`: id of the attachment to get + pub async fn issue_get_issue_attachment( + &self, + owner: &str, + repo: &str, + index: u64, + attachment_id: u64, + ) -> Result<Attachment, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete an issue attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `attachment_id`: id of the attachment to delete + pub async fn issue_delete_issue_attachment( + &self, + owner: &str, + repo: &str, + index: u64, + attachment_id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit an issue attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `attachment_id`: id of the attachment to edit + /// - `body`: See [`EditAttachmentOptions`] + pub async fn issue_edit_issue_attachment( + &self, + owner: &str, + repo: &str, + index: u64, + attachment_id: u64, + body: EditAttachmentOptions, + ) -> Result<Attachment, ForgejoError> { + let request = self + .patch(&format!( + "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List issues that are blocked by this issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_list_blocks( + &self, + owner: &str, + repo: &str, + index: &str, + query: IssueListBlocksQuery, + ) -> Result<Vec<Issue>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/blocks?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Block the issue given in the body by the issue in path + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueMeta`] + pub async fn issue_create_issue_blocking( + &self, + owner: &str, + repo: &str, + index: &str, + body: IssueMeta, + ) -> Result<Issue, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/blocks")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unblock the issue given in the body by the issue in path + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueMeta`] + pub async fn issue_remove_issue_blocking( + &self, + owner: &str, + repo: &str, + index: &str, + body: IssueMeta, + ) -> Result<Issue, ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/blocks")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all comments on an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_get_comments( + &self, + owner: &str, + repo: &str, + index: u64, + query: IssueGetCommentsQuery, + ) -> Result<Vec<Comment>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/comments?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a comment to an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`CreateIssueCommentOption`] + pub async fn issue_create_comment( + &self, + owner: &str, + repo: &str, + index: u64, + body: CreateIssueCommentOption, + ) -> Result<Comment, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/comments")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: this parameter is ignored + /// - `id`: id of comment to delete + pub async fn issue_delete_comment_deprecated( + &self, + owner: &str, + repo: &str, + index: u32, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/{index}/comments/{id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: this parameter is ignored + /// - `id`: id of the comment to edit + /// - `body`: See [`EditIssueCommentOption`] + pub async fn issue_edit_comment_deprecated( + &self, + owner: &str, + repo: &str, + index: u32, + id: u64, + body: EditIssueCommentOption, + ) -> Result<Option<Comment>, ForgejoError> { + let request = self + .patch(&format!( + "repos/{owner}/{repo}/issues/{index}/comments/{id}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(Some(response.json().await?)), + 204 => Ok(None), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// 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. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to create or update a deadline on + /// - `body`: See [`EditDeadlineOption`] + pub async fn issue_edit_issue_deadline( + &self, + owner: &str, + repo: &str, + index: u64, + body: EditDeadlineOption, + ) -> Result<IssueDeadline, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/deadline")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an issue's dependencies, i.e all issues that block this issue. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_list_issue_dependencies( + &self, + owner: &str, + repo: &str, + index: &str, + query: IssueListIssueDependenciesQuery, + ) -> Result<Vec<Issue>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/dependencies?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Make the issue in the url depend on the issue in the form. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueMeta`] + pub async fn issue_create_issue_dependencies( + &self, + owner: &str, + repo: &str, + index: &str, + body: IssueMeta, + ) -> Result<Issue, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/dependencies")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove an issue dependency + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueMeta`] + pub async fn issue_remove_issue_dependencies( + &self, + owner: &str, + repo: &str, + index: &str, + body: IssueMeta, + ) -> Result<Issue, ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/dependencies")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an issue's labels + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_get_labels( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<Vec<Label>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/issues/{index}/labels")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Replace an issue's labels + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueLabelsOption`] + pub async fn issue_replace_labels( + &self, + owner: &str, + repo: &str, + index: u64, + body: IssueLabelsOption, + ) -> Result<Vec<Label>, ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/issues/{index}/labels")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a label to an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`IssueLabelsOption`] + pub async fn issue_add_label( + &self, + owner: &str, + repo: &str, + index: u64, + body: IssueLabelsOption, + ) -> Result<Vec<Label>, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/labels")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove all labels from an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`DeleteLabelsOption`] + pub async fn issue_clear_labels( + &self, + owner: &str, + repo: &str, + index: u64, + body: DeleteLabelsOption, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/labels")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a label from an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `id`: id of the label to remove + /// - `body`: See [`DeleteLabelsOption`] + pub async fn issue_remove_label( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + body: DeleteLabelsOption, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/labels/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Pin an Issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of issue to pin + pub async fn pin_issue(&self, owner: &str, repo: &str, index: u64) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/pin")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unpin an Issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of issue to unpin + pub async fn unpin_issue( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/pin")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Moves the Pin to the given Position + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of issue + /// - `position`: the new position + pub async fn move_issue_pin( + &self, + owner: &str, + repo: &str, + index: u64, + position: u64, + ) -> Result<(), ForgejoError> { + let request = self + .patch(&format!( + "repos/{owner}/{repo}/issues/{index}/pin/{position}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a list reactions of an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_get_issue_reactions( + &self, + owner: &str, + repo: &str, + index: u64, + query: IssueGetIssueReactionsQuery, + ) -> Result<Vec<Reaction>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/reactions?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a reaction to an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `content`: See [`EditReactionOption`] + pub async fn issue_post_issue_reaction( + &self, + owner: &str, + repo: &str, + index: u64, + content: EditReactionOption, + ) -> Result<Reaction, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/reactions")) + .json(&content) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a reaction from an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `content`: See [`EditReactionOption`] + pub async fn issue_delete_issue_reaction( + &self, + owner: &str, + repo: &str, + index: u64, + content: EditReactionOption, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/reactions")) + .json(&content) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete an issue's existing stopwatch. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to stop the stopwatch on + pub async fn issue_delete_stop_watch( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/{index}/stopwatch/delete" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Start stopwatch on an issue. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to create the stopwatch on + pub async fn issue_start_stop_watch( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/issues/{index}/stopwatch/start" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Stop an issue's existing stopwatch. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to stop the stopwatch on + pub async fn issue_stop_stop_watch( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/issues/{index}/stopwatch/stop" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get users who subscribed on an issue. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_subscriptions( + &self, + owner: &str, + repo: &str, + index: u64, + query: IssueSubscriptionsQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/subscriptions?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if user is subscribed to an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_check_subscription( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<WatchInfo, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/subscriptions/check" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Subscribe user to issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `user`: user to subscribe + pub async fn issue_add_subscription( + &self, + owner: &str, + repo: &str, + index: u64, + user: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!( + "repos/{owner}/{repo}/issues/{index}/subscriptions/{user}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + 201 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unsubscribe user from issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `user`: user witch unsubscribe + pub async fn issue_delete_subscription( + &self, + owner: &str, + repo: &str, + index: u64, + user: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/issues/{index}/subscriptions/{user}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + 201 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all comments and events on an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_get_comments_and_timeline( + &self, + owner: &str, + repo: &str, + index: u64, + query: IssueGetCommentsAndTimelineQuery, + ) -> Result<Vec<TimelineComment>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/timeline?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List an issue's tracked times + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + pub async fn issue_tracked_times( + &self, + owner: &str, + repo: &str, + index: u64, + query: IssueTrackedTimesQuery, + ) -> Result<Vec<TrackedTime>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/issues/{index}/times?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add tracked time to a issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `body`: See [`AddTimeOption`] + pub async fn issue_add_time( + &self, + owner: &str, + repo: &str, + index: u64, + body: AddTimeOption, + ) -> Result<TrackedTime, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/issues/{index}/times")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Reset a tracked time of an issue + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue to add tracked time to + pub async fn issue_reset_time( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/times")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete specific tracked time + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the issue + /// - `id`: id of time to delete + pub async fn issue_delete_time( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/issues/{index}/times/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's keys + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_keys( + &self, + owner: &str, + repo: &str, + query: RepoListKeysQuery, + ) -> Result<Vec<DeployKey>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/keys?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a key to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateKeyOption`] + pub async fn repo_create_key( + &self, + owner: &str, + repo: &str, + body: CreateKeyOption, + ) -> Result<DeployKey, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/keys")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a repository's key by id + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the key to get + pub async fn repo_get_key( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<DeployKey, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/keys/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a key from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the key to delete + pub async fn repo_delete_key( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/keys/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get all of a repository's labels + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn issue_list_labels( + &self, + owner: &str, + repo: &str, + query: IssueListLabelsQuery, + ) -> Result<Vec<Label>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/labels?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a label + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateLabelOption`] + pub async fn issue_create_label( + &self, + owner: &str, + repo: &str, + body: CreateLabelOption, + ) -> Result<Label, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/labels")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a single label + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the label to get + pub async fn issue_get_label( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Label, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/labels/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a label + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the label to delete + pub async fn issue_delete_label( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/labels/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a label + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the label to edit + /// - `body`: See [`EditLabelOption`] + pub async fn issue_edit_label( + &self, + owner: &str, + repo: &str, + id: u64, + body: EditLabelOption, + ) -> Result<Label, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/labels/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get languages and number of bytes of code written + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_languages( + &self, + owner: &str, + repo: &str, + ) -> Result<BTreeMap<String, i64>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/languages")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a file or it's LFS object from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: filepath of the file to get + pub async fn repo_get_raw_file_or_lfs( + &self, + owner: &str, + repo: &str, + filepath: &str, + query: RepoGetRawFileOrLfsQuery, + ) -> Result<Vec<u8>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/media/{filepath}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.bytes().await?[..].to_vec()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get all of a repository's opened milestones + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn issue_get_milestones_list( + &self, + owner: &str, + repo: &str, + query: IssueGetMilestonesListQuery, + ) -> Result<Vec<Milestone>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/milestones?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a milestone + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateMilestoneOption`] + pub async fn issue_create_milestone( + &self, + owner: &str, + repo: &str, + body: CreateMilestoneOption, + ) -> Result<Milestone, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/milestones")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a milestone + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: the milestone to get, identified by ID and if not available by name + pub async fn issue_get_milestone( + &self, + owner: &str, + repo: &str, + id: &str, + ) -> Result<Milestone, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/milestones/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a milestone + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: the milestone to delete, identified by ID and if not available by name + pub async fn issue_delete_milestone( + &self, + owner: &str, + repo: &str, + id: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/milestones/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a milestone + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: the milestone to edit, identified by ID and if not available by name + /// - `body`: See [`EditMilestoneOption`] + pub async fn issue_edit_milestone( + &self, + owner: &str, + repo: &str, + id: &str, + body: EditMilestoneOption, + ) -> Result<Milestone, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/milestones/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Sync a mirrored repository + /// + /// - `owner`: owner of the repo to sync + /// - `repo`: name of the repo to sync + pub async fn repo_mirror_sync(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/mirror-sync")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns if new Issue Pins are allowed + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_new_pin_allowed( + &self, + owner: &str, + repo: &str, + ) -> Result<NewIssuePinsAllowed, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/new_pin_allowed")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List users's notification threads on a specific repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn notify_get_repo_list( + &self, + owner: &str, + repo: &str, + query: NotifyGetRepoListQuery, + ) -> Result<Vec<NotificationThread>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/notifications?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Mark notification threads as read, pinned or unread on a specific repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn notify_read_repo_list( + &self, + owner: &str, + repo: &str, + query: NotifyReadRepoListQuery, + ) -> Result<Vec<NotificationThread>, ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/notifications?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 205 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's pull requests + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_pull_requests( + &self, + owner: &str, + repo: &str, + query: RepoListPullRequestsQuery, + ) -> Result<Vec<PullRequest>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreatePullRequestOption`] + pub async fn repo_create_pull_request( + &self, + owner: &str, + repo: &str, + body: CreatePullRequestOption, + ) -> Result<PullRequest, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/pulls")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's pinned pull requests + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_pinned_pull_requests( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<PullRequest>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/pinned")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a pull request by base and head + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `base`: base of the pull request to get + /// - `head`: head of the pull request to get + pub async fn repo_get_pull_request_by_base_head( + &self, + owner: &str, + repo: &str, + base: &str, + head: &str, + ) -> Result<PullRequest, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/{base}/{head}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to get + pub async fn repo_get_pull_request( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<PullRequest, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/{index}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a pull request. If using deadline only the date will be taken into account, and time of day ignored. + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to edit + /// - `body`: See [`EditPullRequestOption`] + pub async fn repo_edit_pull_request( + &self, + owner: &str, + repo: &str, + index: u64, + body: EditPullRequestOption, + ) -> Result<PullRequest, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/pulls/{index}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a pull request diff or patch + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to get + /// - `diffType`: whether the output is diff or patch + pub async fn repo_download_pull_diff_or_patch( + &self, + owner: &str, + repo: &str, + index: u64, + diff_type: &str, + query: RepoDownloadPullDiffOrPatchQuery, + ) -> Result<String, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/pulls/{index}.{diff_type}?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get commits for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to get + pub async fn repo_get_pull_request_commits( + &self, + owner: &str, + repo: &str, + index: u64, + query: RepoGetPullRequestCommitsQuery, + ) -> Result<(CommitListHeaders, Vec<Commit>), ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/pulls/{index}/commits?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok((response.headers().try_into()?, response.json().await?)), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get changed files for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to get + pub async fn repo_get_pull_request_files( + &self, + owner: &str, + repo: &str, + index: u64, + query: RepoGetPullRequestFilesQuery, + ) -> Result<(ChangedFileListHeaders, Vec<ChangedFile>), ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/{index}/files?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok((response.headers().try_into()?, response.json().await?)), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a pull request has been merged + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + pub async fn repo_pull_request_is_merged( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/{index}/merge")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Merge a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to merge + /// - `body`: See [`MergePullRequestOption`] + pub async fn repo_merge_pull_request( + &self, + owner: &str, + repo: &str, + index: u64, + body: MergePullRequestOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/pulls/{index}/merge")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Cancel the scheduled auto merge for the given pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to merge + pub async fn repo_cancel_scheduled_auto_merge( + &self, + owner: &str, + repo: &str, + index: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/pulls/{index}/merge")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// create review requests for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `body`: See [`PullReviewRequestOptions`] + pub async fn repo_create_pull_review_requests( + &self, + owner: &str, + repo: &str, + index: u64, + body: PullReviewRequestOptions, + ) -> Result<Vec<PullReview>, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/pulls/{index}/requested_reviewers" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// cancel review requests for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `body`: See [`PullReviewRequestOptions`] + pub async fn repo_delete_pull_review_requests( + &self, + owner: &str, + repo: &str, + index: u64, + body: PullReviewRequestOptions, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/pulls/{index}/requested_reviewers" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all reviews for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + pub async fn repo_list_pull_reviews( + &self, + owner: &str, + repo: &str, + index: u64, + query: RepoListPullReviewsQuery, + ) -> Result<Vec<PullReview>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a review to an pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `body`: See [`CreatePullReviewOptions`] + pub async fn repo_create_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + body: CreatePullReviewOptions, + ) -> Result<PullReview, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/pulls/{index}/reviews")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a specific review for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + pub async fn repo_get_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + ) -> Result<PullReview, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Submit a pending review to an pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + /// - `body`: See [`SubmitPullReviewOptions`] + pub async fn repo_submit_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + body: SubmitPullReviewOptions, + ) -> Result<PullReview, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a specific review from a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + pub async fn repo_delete_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a specific review for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + pub async fn repo_get_pull_review_comments( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + ) -> Result<Vec<PullReviewComment>, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a new comment to a pull request review + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + /// - `body`: See [`serde_json::Value`] + pub async fn repo_create_pull_review_comment( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + body: serde_json::Value, + ) -> Result<PullReviewComment, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a pull review comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + /// - `comment`: id of the comment + pub async fn repo_get_pull_review_comment( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + comment: u64, + ) -> Result<PullReviewComment, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a pull review comment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + /// - `comment`: id of the comment + pub async fn repo_delete_pull_review_comment( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + comment: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Dismiss a review for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + /// - `body`: See [`DismissPullReviewOptions`] + pub async fn repo_dismiss_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + body: DismissPullReviewOptions, + ) -> Result<PullReview, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Cancel to dismiss a review for a pull request + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request + /// - `id`: id of the review + pub async fn repo_un_dismiss_pull_review( + &self, + owner: &str, + repo: &str, + index: u64, + id: u64, + ) -> Result<PullReview, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/undismissals" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Merge PR's baseBranch into headBranch + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `index`: index of the pull request to get + pub async fn repo_update_pull_request( + &self, + owner: &str, + repo: &str, + index: u64, + query: RepoUpdatePullRequestQuery, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/pulls/{index}/update?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get all push mirrors of the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_push_mirrors( + &self, + owner: &str, + repo: &str, + query: RepoListPushMirrorsQuery, + ) -> Result<Vec<PushMirror>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/push_mirrors?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// add a push mirror to the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreatePushMirrorOption`] + pub async fn repo_add_push_mirror( + &self, + owner: &str, + repo: &str, + body: CreatePushMirrorOption, + ) -> Result<PushMirror, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/push_mirrors")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Sync all push mirrored repository + /// + /// - `owner`: owner of the repo to sync + /// - `repo`: name of the repo to sync + pub async fn repo_push_mirror_sync(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/push_mirrors-sync")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get push mirror of the repository by remoteName + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `name`: remote name of push mirror + pub async fn repo_get_push_mirror_by_remote_name( + &self, + owner: &str, + repo: &str, + name: &str, + ) -> Result<PushMirror, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/push_mirrors/{name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// deletes a push mirror from a repository by remoteName + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `name`: remote name of the pushMirror + pub async fn repo_delete_push_mirror( + &self, + owner: &str, + repo: &str, + name: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/push_mirrors/{name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a file from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `filepath`: filepath of the file to get + pub async fn repo_get_raw_file( + &self, + owner: &str, + repo: &str, + filepath: &str, + query: RepoGetRawFileQuery, + ) -> Result<Vec<u8>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/raw/{filepath}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.bytes().await?[..].to_vec()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's releases + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_releases( + &self, + owner: &str, + repo: &str, + query: RepoListReleasesQuery, + ) -> Result<Vec<Release>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/releases?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a release + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateReleaseOption`] + pub async fn repo_create_release( + &self, + owner: &str, + repo: &str, + body: CreateReleaseOption, + ) -> Result<Release, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/releases")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_latest_release( + &self, + owner: &str, + repo: &str, + ) -> Result<Release, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/releases/latest")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a release by tag name + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `tag`: tag name of the release to get + pub async fn repo_get_release_by_tag( + &self, + owner: &str, + repo: &str, + tag: &str, + ) -> Result<Release, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/releases/tags/{tag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a release by tag name + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `tag`: tag name of the release to delete + pub async fn repo_delete_release_by_tag( + &self, + owner: &str, + repo: &str, + tag: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/releases/tags/{tag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a release + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release to get + pub async fn repo_get_release( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Release, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/releases/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a release + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release to delete + pub async fn repo_delete_release( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/releases/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a release + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release to edit + /// - `body`: See [`EditReleaseOption`] + pub async fn repo_edit_release( + &self, + owner: &str, + repo: &str, + id: u64, + body: EditReleaseOption, + ) -> Result<Release, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/releases/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List release's attachments + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release + pub async fn repo_list_release_attachments( + &self, + owner: &str, + repo: &str, + id: u64, + ) -> Result<Vec<Attachment>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/releases/{id}/assets")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a release attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release + /// - `attachment`: attachment to upload + pub async fn repo_create_release_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment: Vec<u8>, + query: RepoCreateReleaseAttachmentQuery, + ) -> Result<Attachment, ForgejoError> { + let request = self + .post(&format!( + "repos/{owner}/{repo}/releases/{id}/assets?{query}" + )) + .multipart( + reqwest::multipart::Form::new().part( + "attachment", + reqwest::multipart::Part::bytes(attachment) + .file_name("file") + .mime_str("*/*") + .unwrap(), + ), + ) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a release attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release + /// - `attachment_id`: id of the attachment to get + pub async fn repo_get_release_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + ) -> Result<Attachment, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a release attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release + /// - `attachment_id`: id of the attachment to delete + pub async fn repo_delete_release_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!( + "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a release attachment + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the release + /// - `attachment_id`: id of the attachment to edit + /// - `body`: See [`EditAttachmentOptions`] + pub async fn repo_edit_release_attachment( + &self, + owner: &str, + repo: &str, + id: u64, + attachment_id: u64, + body: EditAttachmentOptions, + ) -> Result<Attachment, ForgejoError> { + let request = self + .patch(&format!( + "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}" + )) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Return all users that can be requested to review in this repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_reviewers( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/reviewers")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a repository's actions runner registration token + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_runner_registration_token( + &self, + owner: &str, + repo: &str, + ) -> Result<RegistrationTokenHeaders, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/runners/registration-token")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.headers().try_into()?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get signing-key.gpg for given repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_signing_key(&self, owner: &str, repo: &str) -> Result<String, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/signing-key.gpg")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's stargazers + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_stargazers( + &self, + owner: &str, + repo: &str, + query: RepoListStargazersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/stargazers?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a commit's statuses + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: sha of the commit + pub async fn repo_list_statuses( + &self, + owner: &str, + repo: &str, + sha: &str, + query: RepoListStatusesQuery, + ) -> Result<Vec<CommitStatus>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/statuses/{sha}?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a commit status + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `sha`: sha of the commit + /// - `body`: See [`CreateStatusOption`] + pub async fn repo_create_status( + &self, + owner: &str, + repo: &str, + sha: &str, + body: CreateStatusOption, + ) -> Result<CommitStatus, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/statuses/{sha}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's watchers + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_subscribers( + &self, + owner: &str, + repo: &str, + query: RepoListSubscribersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/subscribers?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if the current user is watching a repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn user_current_check_subscription( + &self, + owner: &str, + repo: &str, + ) -> Result<WatchInfo, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/subscription")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Watch a repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn user_current_put_subscription( + &self, + owner: &str, + repo: &str, + ) -> Result<WatchInfo, ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/subscription")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unwatch a repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn user_current_delete_subscription( + &self, + owner: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/subscription")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List tag protections for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_tag_protection( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<TagProtection>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/tag_protections")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a tag protections for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateTagProtectionOption`] + pub async fn repo_create_tag_protection( + &self, + owner: &str, + repo: &str, + body: CreateTagProtectionOption, + ) -> Result<TagProtection, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/tag_protections")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a specific tag protection for the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of the tag protect to get + pub async fn repo_get_tag_protection( + &self, + owner: &str, + repo: &str, + id: u32, + ) -> Result<TagProtection, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/tag_protections/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a specific tag protection for the repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of protected tag + pub async fn repo_delete_tag_protection( + &self, + owner: &str, + repo: &str, + id: u32, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/tag_protections/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a tag protections for a repository. Only fields that are set will be changed + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `id`: id of protected tag + /// - `body`: See [`EditTagProtectionOption`] + pub async fn repo_edit_tag_protection( + &self, + owner: &str, + repo: &str, + id: u32, + body: EditTagProtectionOption, + ) -> Result<TagProtection, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/tag_protections/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's tags + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_tags( + &self, + owner: &str, + repo: &str, + query: RepoListTagsQuery, + ) -> Result<Vec<Tag>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/tags?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a new git tag in a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateTagOption`] + pub async fn repo_create_tag( + &self, + owner: &str, + repo: &str, + body: CreateTagOption, + ) -> Result<Tag, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/tags")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get the tag of a repository by tag name + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `tag`: name of tag + pub async fn repo_get_tag( + &self, + owner: &str, + repo: &str, + tag: &str, + ) -> Result<Tag, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/tags/{tag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a repository's tag by name + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `tag`: name of tag to delete + pub async fn repo_delete_tag( + &self, + owner: &str, + repo: &str, + tag: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/tags/{tag}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repository's teams + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_teams( + &self, + owner: &str, + repo: &str, + ) -> Result<Vec<Team>, ForgejoError> { + let request = self.get(&format!("repos/{owner}/{repo}/teams")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if a team is assigned to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `team`: team name + pub async fn repo_check_team( + &self, + owner: &str, + repo: &str, + team: &str, + ) -> Result<Team, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/teams/{team}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a team to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `team`: team name + pub async fn repo_add_team( + &self, + owner: &str, + repo: &str, + team: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/teams/{team}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a team from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `team`: team name + pub async fn repo_delete_team( + &self, + owner: &str, + repo: &str, + team: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/teams/{team}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a repo's tracked times + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_tracked_times( + &self, + owner: &str, + repo: &str, + query: RepoTrackedTimesQuery, + ) -> Result<Vec<TrackedTime>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/times?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a user's tracked times in a repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `user`: username of user + pub async fn user_tracked_times( + &self, + owner: &str, + repo: &str, + user: &str, + ) -> Result<Vec<TrackedTime>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/times/{user}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get list of topics that a repository has + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_list_topics( + &self, + owner: &str, + repo: &str, + query: RepoListTopicsQuery, + ) -> Result<TopicName, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/topics?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Replace list of topics for a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`RepoTopicOptions`] + pub async fn repo_update_topics( + &self, + owner: &str, + repo: &str, + body: RepoTopicOptions, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/topics")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a topic to a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `topic`: name of the topic to add + pub async fn repo_add_topic( + &self, + owner: &str, + repo: &str, + topic: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("repos/{owner}/{repo}/topics/{topic}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a topic from a repository + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `topic`: name of the topic to delete + pub async fn repo_delete_topic( + &self, + owner: &str, + repo: &str, + topic: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/topics/{topic}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Transfer a repo ownership + /// + /// - `owner`: owner of the repo to transfer + /// - `repo`: name of the repo to transfer + /// - `body`: Transfer Options + + /// See [`TransferRepoOption`] + pub async fn repo_transfer( + &self, + owner: &str, + repo: &str, + body: TransferRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/transfer")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 202 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Accept a repo transfer + /// + /// - `owner`: owner of the repo to transfer + /// - `repo`: name of the repo to transfer + pub async fn accept_repo_transfer( + &self, + owner: &str, + repo: &str, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/transfer/accept")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 202 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Reject a repo transfer + /// + /// - `owner`: owner of the repo to transfer + /// - `repo`: name of the repo to transfer + pub async fn reject_repo_transfer( + &self, + owner: &str, + repo: &str, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/transfer/reject")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a wiki page + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `body`: See [`CreateWikiPageOptions`] + pub async fn repo_create_wiki_page( + &self, + owner: &str, + repo: &str, + body: CreateWikiPageOptions, + ) -> Result<WikiPage, ForgejoError> { + let request = self + .post(&format!("repos/{owner}/{repo}/wiki/new")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a wiki page + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `pageName`: name of the page + pub async fn repo_get_wiki_page( + &self, + owner: &str, + repo: &str, + page_name: &str, + ) -> Result<WikiPage, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/wiki/page/{page_name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a wiki page + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `pageName`: name of the page + pub async fn repo_delete_wiki_page( + &self, + owner: &str, + repo: &str, + page_name: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("repos/{owner}/{repo}/wiki/page/{page_name}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a wiki page + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `pageName`: name of the page + /// - `body`: See [`CreateWikiPageOptions`] + pub async fn repo_edit_wiki_page( + &self, + owner: &str, + repo: &str, + page_name: &str, + body: CreateWikiPageOptions, + ) -> Result<WikiPage, ForgejoError> { + let request = self + .patch(&format!("repos/{owner}/{repo}/wiki/page/{page_name}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get all wiki pages + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn repo_get_wiki_pages( + &self, + owner: &str, + repo: &str, + query: RepoGetWikiPagesQuery, + ) -> Result<Vec<WikiPageMetaData>, ForgejoError> { + let request = self + .get(&format!("repos/{owner}/{repo}/wiki/pages?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get revisions of a wiki page + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + /// - `pageName`: name of the page + pub async fn repo_get_wiki_page_revisions( + &self, + owner: &str, + repo: &str, + page_name: &str, + query: RepoGetWikiPageRevisionsQuery, + ) -> Result<WikiCommitList, ForgejoError> { + let request = self + .get(&format!( + "repos/{owner}/{repo}/wiki/revisions/{page_name}?{query}" + )) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repository using a template + /// + /// - `template_owner`: name of the template repository owner + /// - `template_repo`: name of the template repository + /// - `body`: See [`GenerateRepoOption`] + pub async fn generate_repo( + &self, + template_owner: &str, + template_repo: &str, + body: GenerateRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self + .post(&format!("repos/{template_owner}/{template_repo}/generate")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a repository by id + /// + /// - `id`: id of the repo to get + pub async fn repo_get_by_id(&self, id: u64) -> Result<Repository, ForgejoError> { + let request = self.get(&format!("repositories/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get instance's global settings for api + pub async fn get_general_api_settings(&self) -> Result<GeneralAPISettings, ForgejoError> { + let request = self.get("settings/api").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get instance's global settings for Attachment + pub async fn get_general_attachment_settings( + &self, + ) -> Result<GeneralAttachmentSettings, ForgejoError> { + let request = self.get("settings/attachment").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get instance's global settings for repositories + pub async fn get_general_repository_settings( + &self, + ) -> Result<GeneralRepoSettings, ForgejoError> { + let request = self.get("settings/repository").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get instance's global settings for ui + pub async fn get_general_ui_settings(&self) -> Result<GeneralUISettings, ForgejoError> { + let request = self.get("settings/ui").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get default signing-key.gpg + pub async fn get_signing_key(&self) -> Result<String, ForgejoError> { + let request = self.get("signing-key.gpg").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a team + /// + /// - `id`: id of the team to get + pub async fn org_get_team(&self, id: u64) -> Result<Team, ForgejoError> { + let request = self.get(&format!("teams/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a team + /// + /// - `id`: id of the team to delete + pub async fn org_delete_team(&self, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("teams/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Edit a team + /// + /// - `id`: id of the team to edit + /// - `body`: See [`EditTeamOption`] + pub async fn org_edit_team(&self, id: u32, body: EditTeamOption) -> Result<Team, ForgejoError> { + let request = self.patch(&format!("teams/{id}")).json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a team's activity feeds + /// + /// - `id`: id of the team + pub async fn org_list_team_activity_feeds( + &self, + id: u64, + query: OrgListTeamActivityFeedsQuery, + ) -> Result<Vec<Activity>, ForgejoError> { + let request = self + .get(&format!("teams/{id}/activities/feeds?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a team's members + /// + /// - `id`: id of the team + pub async fn org_list_team_members( + &self, + id: u64, + query: OrgListTeamMembersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self.get(&format!("teams/{id}/members?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a particular member of team + /// + /// - `id`: id of the team + /// - `username`: username of the member to list + pub async fn org_list_team_member( + &self, + id: u64, + username: &str, + ) -> Result<User, ForgejoError> { + let request = self + .get(&format!("teams/{id}/members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a team member + /// + /// - `id`: id of the team + /// - `username`: username of the user to add + pub async fn org_add_team_member(&self, id: u64, username: &str) -> Result<(), ForgejoError> { + let request = self + .put(&format!("teams/{id}/members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a team member + /// + /// - `id`: id of the team + /// - `username`: username of the user to remove + pub async fn org_remove_team_member( + &self, + id: u64, + username: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("teams/{id}/members/{username}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a team's repos + /// + /// - `id`: id of the team + pub async fn org_list_team_repos( + &self, + id: u64, + query: OrgListTeamReposQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self.get(&format!("teams/{id}/repos?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a particular repo of team + /// + /// - `id`: id of the team + /// - `org`: organization that owns the repo to list + /// - `repo`: name of the repo to list + pub async fn org_list_team_repo( + &self, + id: u64, + org: &str, + repo: &str, + ) -> Result<Repository, ForgejoError> { + let request = self + .get(&format!("teams/{id}/repos/{org}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add a repository to a team + /// + /// - `id`: id of the team + /// - `org`: organization that owns the repo to add + /// - `repo`: name of the repo to add + pub async fn org_add_team_repository( + &self, + id: u64, + org: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("teams/{id}/repos/{org}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a repository from a team + /// + /// - `id`: id of the team + /// - `org`: organization that owns the repo to remove + /// - `repo`: name of the repo to remove + pub async fn org_remove_team_repository( + &self, + id: u64, + org: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("teams/{id}/repos/{org}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// search topics via keyword + /// + pub async fn topic_search( + &self, + query: TopicSearchQuery, + ) -> Result<Vec<TopicResponse>, ForgejoError> { + let request = self.get(&format!("topics/search?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get the authenticated user + pub async fn user_get_current(&self) -> Result<User, ForgejoError> { + let request = self.get("user").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get an user's actions runner registration token + pub async fn user_get_runner_registration_token( + &self, + ) -> Result<RegistrationTokenHeaders, ForgejoError> { + let request = self + .get("user/actions/runners/registration-token") + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.headers().try_into()?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create or Update a secret value in a user scope + /// + /// - `secretname`: name of the secret + /// - `body`: See [`CreateOrUpdateSecretOption`] + pub async fn update_user_secret( + &self, + secretname: &str, + body: CreateOrUpdateSecretOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("user/actions/secrets/{secretname}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a secret in a user scope + /// + /// - `secretname`: name of the secret + pub async fn delete_user_secret(&self, secretname: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("user/actions/secrets/{secretname}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get the user-level list of variables which is created by current doer + /// + pub async fn get_user_variables_list( + &self, + query: GetUserVariablesListQuery, + ) -> Result<Vec<ActionVariable>, ForgejoError> { + let request = self + .get(&format!("user/actions/variables?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a user-level variable which is created by current doer + /// + /// - `variablename`: name of the variable + pub async fn get_user_variable( + &self, + variablename: &str, + ) -> Result<ActionVariable, ForgejoError> { + let request = self + .get(&format!("user/actions/variables/{variablename}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a user-level variable which is created by current doer + /// + /// - `variablename`: name of the variable + /// - `body`: See [`UpdateVariableOption`] + pub async fn update_user_variable( + &self, + variablename: &str, + body: UpdateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .put(&format!("user/actions/variables/{variablename}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a user-level variable + /// + /// - `variablename`: name of the variable + /// - `body`: See [`CreateVariableOption`] + pub async fn create_user_variable( + &self, + variablename: &str, + body: CreateVariableOption, + ) -> Result<(), ForgejoError> { + let request = self + .post(&format!("user/actions/variables/{variablename}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a user-level variable which is created by current doer + /// + /// - `variablename`: name of the variable + pub async fn delete_user_variable(&self, variablename: &str) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("user/actions/variables/{variablename}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(()), + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's oauth2 applications + /// + pub async fn user_get_oauth2_applications( + &self, + query: UserGetOAuth2ApplicationsQuery, + ) -> Result<Vec<OAuth2Application>, ForgejoError> { + let request = self + .get(&format!("user/applications/oauth2?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// creates a new OAuth2 application + /// + /// - `body`: See [`CreateOAuth2ApplicationOptions`] + pub async fn user_create_oauth2_application( + &self, + body: CreateOAuth2ApplicationOptions, + ) -> Result<OAuth2Application, ForgejoError> { + let request = self.post("user/applications/oauth2").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// get an OAuth2 Application + /// + /// - `id`: Application ID to be found + pub async fn user_get_oauth2_application( + &self, + id: u64, + ) -> Result<OAuth2Application, ForgejoError> { + let request = self + .get(&format!("user/applications/oauth2/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// delete an OAuth2 Application + /// + /// - `id`: token to be deleted + pub async fn user_delete_oauth2_application(&self, id: u64) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("user/applications/oauth2/{id}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// update an OAuth2 Application, this includes regenerating the client secret + /// + /// - `id`: application to be updated + /// - `body`: See [`CreateOAuth2ApplicationOptions`] + pub async fn user_update_oauth2_application( + &self, + id: u64, + body: CreateOAuth2ApplicationOptions, + ) -> Result<OAuth2Application, ForgejoError> { + let request = self + .patch(&format!("user/applications/oauth2/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update Avatar + /// + /// - `body`: See [`UpdateUserAvatarOption`] + pub async fn user_update_avatar( + &self, + body: UpdateUserAvatarOption, + ) -> Result<(), ForgejoError> { + let request = self.post("user/avatar").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete Avatar + pub async fn user_delete_avatar(&self) -> Result<(), ForgejoError> { + let request = self.delete("user/avatar").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Blocks a user from the doer. + /// + /// - `username`: username of the user + pub async fn user_block_user(&self, username: &str) -> Result<(), ForgejoError> { + let request = self.put(&format!("user/block/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's email addresses + pub async fn user_list_emails(&self) -> Result<Vec<Email>, ForgejoError> { + let request = self.get("user/emails").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Add email addresses + /// + /// - `body`: See [`CreateEmailOption`] + pub async fn user_add_email( + &self, + body: CreateEmailOption, + ) -> Result<Vec<Email>, ForgejoError> { + let request = self.post("user/emails").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete email addresses + /// + /// - `body`: See [`DeleteEmailOption`] + pub async fn user_delete_email(&self, body: DeleteEmailOption) -> Result<(), ForgejoError> { + let request = self.delete("user/emails").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's followers + /// + pub async fn user_current_list_followers( + &self, + query: UserCurrentListFollowersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self.get(&format!("user/followers?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the users that the authenticated user is following + /// + pub async fn user_current_list_following( + &self, + query: UserCurrentListFollowingQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self.get(&format!("user/following?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check whether a user is followed by the authenticated user + /// + /// - `username`: username of followed user + pub async fn user_current_check_following(&self, username: &str) -> Result<(), ForgejoError> { + let request = self.get(&format!("user/following/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Follow a user + /// + /// - `username`: username of user to follow + pub async fn user_current_put_follow(&self, username: &str) -> Result<(), ForgejoError> { + let request = self.put(&format!("user/following/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unfollow a user + /// + /// - `username`: username of user to unfollow + pub async fn user_current_delete_follow(&self, username: &str) -> Result<(), ForgejoError> { + let request = self.delete(&format!("user/following/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a Token to verify + pub async fn get_verification_token(&self) -> Result<String, ForgejoError> { + let request = self.get("user/gpg_key_token").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.text().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Verify a GPG key + pub async fn user_verify_gpg_key(&self) -> Result<GPGKey, ForgejoError> { + let request = self.post("user/gpg_key_verify").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's GPG keys + /// + pub async fn user_current_list_gpg_keys( + &self, + query: UserCurrentListGpgKeysQuery, + ) -> Result<Vec<GPGKey>, ForgejoError> { + let request = self.get(&format!("user/gpg_keys?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a GPG key + /// + /// - `Form`: See [`CreateGPGKeyOption`] + pub async fn user_current_post_gpg_key( + &self, + form: CreateGPGKeyOption, + ) -> Result<GPGKey, ForgejoError> { + let request = self.post("user/gpg_keys").json(&form).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a GPG key + /// + /// - `id`: id of key to get + pub async fn user_current_get_gpg_key(&self, id: u64) -> Result<GPGKey, ForgejoError> { + let request = self.get(&format!("user/gpg_keys/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Remove a GPG key + /// + /// - `id`: id of key to delete + pub async fn user_current_delete_gpg_key(&self, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("user/gpg_keys/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's webhooks + /// + pub async fn user_list_hooks( + &self, + query: UserListHooksQuery, + ) -> Result<Vec<Hook>, ForgejoError> { + let request = self.get(&format!("user/hooks?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a hook + /// + /// - `body`: See [`CreateHookOption`] + pub async fn user_create_hook(&self, body: CreateHookOption) -> Result<Hook, ForgejoError> { + let request = self.post("user/hooks").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a hook + /// + /// - `id`: id of the hook to get + pub async fn user_get_hook(&self, id: u64) -> Result<Hook, ForgejoError> { + let request = self.get(&format!("user/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a hook + /// + /// - `id`: id of the hook to delete + pub async fn user_delete_hook(&self, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("user/hooks/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update a hook + /// + /// - `id`: id of the hook to update + /// - `body`: See [`EditHookOption`] + pub async fn user_edit_hook( + &self, + id: u64, + body: EditHookOption, + ) -> Result<Hook, ForgejoError> { + let request = self + .patch(&format!("user/hooks/{id}")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's public keys + /// + pub async fn user_current_list_keys( + &self, + query: UserCurrentListKeysQuery, + ) -> Result<Vec<PublicKey>, ForgejoError> { + let request = self.get(&format!("user/keys?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a public key + /// + /// - `body`: See [`CreateKeyOption`] + pub async fn user_current_post_key( + &self, + body: CreateKeyOption, + ) -> Result<PublicKey, ForgejoError> { + let request = self.post("user/keys").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a public key + /// + /// - `id`: id of key to get + pub async fn user_current_get_key(&self, id: u64) -> Result<PublicKey, ForgejoError> { + let request = self.get(&format!("user/keys/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Delete a public key + /// + /// - `id`: id of key to delete + pub async fn user_current_delete_key(&self, id: u64) -> Result<(), ForgejoError> { + let request = self.delete(&format!("user/keys/{id}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's blocked users + /// + pub async fn user_list_blocked_users( + &self, + query: UserListBlockedUsersQuery, + ) -> Result<Vec<BlockedUser>, ForgejoError> { + let request = self.get(&format!("user/list_blocked?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the current user's organizations + /// + pub async fn org_list_current_user_orgs( + &self, + query: OrgListCurrentUserOrgsQuery, + ) -> Result<Vec<Organization>, ForgejoError> { + let request = self.get(&format!("user/orgs?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the repos that the authenticated user owns + /// + pub async fn user_current_list_repos( + &self, + query: UserCurrentListReposQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self.get(&format!("user/repos?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create a repository + /// + /// - `body`: See [`CreateRepoOption`] + pub async fn create_current_user_repo( + &self, + body: CreateRepoOption, + ) -> Result<Repository, ForgejoError> { + let request = self.post("user/repos").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get user settings + pub async fn get_user_settings(&self) -> Result<UserSettings, ForgejoError> { + let request = self.get("user/settings").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Update user settings + /// + /// - `body`: See [`UserSettingsOptions`] + pub async fn update_user_settings( + &self, + body: UserSettingsOptions, + ) -> Result<UserSettings, ForgejoError> { + let request = self.patch("user/settings").json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// The repos that the authenticated user has starred + /// + pub async fn user_current_list_starred( + &self, + query: UserCurrentListStarredQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self.get(&format!("user/starred?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Whether the authenticated is starring the repo + /// + /// - `owner`: owner of the repo + /// - `repo`: name of the repo + pub async fn user_current_check_starring( + &self, + owner: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self.get(&format!("user/starred/{owner}/{repo}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Star the given repo + /// + /// - `owner`: owner of the repo to star + /// - `repo`: name of the repo to star + pub async fn user_current_put_star(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> { + let request = self.put(&format!("user/starred/{owner}/{repo}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unstar the given repo + /// + /// - `owner`: owner of the repo to unstar + /// - `repo`: name of the repo to unstar + pub async fn user_current_delete_star( + &self, + owner: &str, + repo: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("user/starred/{owner}/{repo}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get list of all existing stopwatches + /// + pub async fn user_get_stop_watches( + &self, + query: UserGetStopWatchesQuery, + ) -> Result<Vec<StopWatch>, ForgejoError> { + let request = self.get(&format!("user/stopwatches?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List repositories watched by the authenticated user + /// + pub async fn user_current_list_subscriptions( + &self, + query: UserCurrentListSubscriptionsQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self.get(&format!("user/subscriptions?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List all the teams a user belongs to + /// + pub async fn user_list_teams( + &self, + query: UserListTeamsQuery, + ) -> Result<Vec<Team>, ForgejoError> { + let request = self.get(&format!("user/teams?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the current user's tracked times + /// + pub async fn user_current_tracked_times( + &self, + query: UserCurrentTrackedTimesQuery, + ) -> Result<Vec<TrackedTime>, ForgejoError> { + let request = self.get(&format!("user/times?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Unblocks a user from the doer. + /// + /// - `username`: username of the user + pub async fn user_unblock_user(&self, username: &str) -> Result<(), ForgejoError> { + let request = self.put(&format!("user/unblock/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Search for users + /// + pub async fn user_search( + &self, + query: UserSearchQuery, + ) -> Result<UserSearchResponse, ForgejoError> { + let request = self.get(&format!("users/search?{query}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a user + /// + /// - `username`: username of user to get + pub async fn user_get(&self, username: &str) -> Result<User, ForgejoError> { + let request = self.get(&format!("users/{username}")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a user's activity feeds + /// + /// - `username`: username of user + pub async fn user_list_activity_feeds( + &self, + username: &str, + query: UserListActivityFeedsQuery, + ) -> Result<Vec<Activity>, ForgejoError> { + let request = self + .get(&format!("users/{username}/activities/feeds?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the given user's followers + /// + /// - `username`: username of user + pub async fn user_list_followers( + &self, + username: &str, + query: UserListFollowersQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("users/{username}/followers?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the users that the given user is following + /// + /// - `username`: username of user + pub async fn user_list_following( + &self, + username: &str, + query: UserListFollowingQuery, + ) -> Result<Vec<User>, ForgejoError> { + let request = self + .get(&format!("users/{username}/following?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Check if one user is following another user + /// + /// - `username`: username of following user + /// - `target`: username of followed user + pub async fn user_check_following( + &self, + username: &str, + target: &str, + ) -> Result<(), ForgejoError> { + let request = self + .get(&format!("users/{username}/following/{target}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the given user's GPG keys + /// + /// - `username`: username of user + pub async fn user_list_gpg_keys( + &self, + username: &str, + query: UserListGpgKeysQuery, + ) -> Result<Vec<GPGKey>, ForgejoError> { + let request = self + .get(&format!("users/{username}/gpg_keys?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get a user's heatmap + /// + /// - `username`: username of user to get + pub async fn user_get_heatmap_data( + &self, + username: &str, + ) -> Result<Vec<UserHeatmapData>, ForgejoError> { + let request = self.get(&format!("users/{username}/heatmap")).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the given user's public keys + /// + /// - `username`: username of user + pub async fn user_list_keys( + &self, + username: &str, + query: UserListKeysQuery, + ) -> Result<Vec<PublicKey>, ForgejoError> { + let request = self + .get(&format!("users/{username}/keys?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List a user's organizations + /// + /// - `username`: username of user + pub async fn org_list_user_orgs( + &self, + username: &str, + query: OrgListUserOrgsQuery, + ) -> Result<Vec<Organization>, ForgejoError> { + let request = self + .get(&format!("users/{username}/orgs?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Get user permissions in organization + /// + /// - `username`: username of user + /// - `org`: name of the organization + pub async fn org_get_user_permissions( + &self, + username: &str, + org: &str, + ) -> Result<OrganizationPermissions, ForgejoError> { + let request = self + .get(&format!("users/{username}/orgs/{org}/permissions")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the repos owned by the given user + /// + /// - `username`: username of user + pub async fn user_list_repos( + &self, + username: &str, + query: UserListReposQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self + .get(&format!("users/{username}/repos?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// The repos that the given user has starred + /// + /// - `username`: username of user + pub async fn user_list_starred( + &self, + username: &str, + query: UserListStarredQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self + .get(&format!("users/{username}/starred?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the repositories watched by a user + /// + /// - `username`: username of the user + pub async fn user_list_subscriptions( + &self, + username: &str, + query: UserListSubscriptionsQuery, + ) -> Result<Vec<Repository>, ForgejoError> { + let request = self + .get(&format!("users/{username}/subscriptions?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// List the authenticated user's access tokens + /// + /// - `username`: username of user + pub async fn user_get_tokens( + &self, + username: &str, + query: UserGetTokensQuery, + ) -> Result<Vec<AccessToken>, ForgejoError> { + let request = self + .get(&format!("users/{username}/tokens?{query}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Create an access token + /// + /// - `username`: username of user + /// - `body`: See [`CreateAccessTokenOption`] + pub async fn user_create_token( + &self, + username: &str, + body: CreateAccessTokenOption, + ) -> Result<AccessToken, ForgejoError> { + let request = self + .post(&format!("users/{username}/tokens")) + .json(&body) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 201 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// delete an access token + /// + /// - `username`: username of user + /// - `token`: token to be deleted, identified by ID and if not available by name + pub async fn user_delete_access_token( + &self, + username: &str, + token: &str, + ) -> Result<(), ForgejoError> { + let request = self + .delete(&format!("users/{username}/tokens/{token}")) + .build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 204 => Ok(()), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + /// Returns the version of the Forgejo application + pub async fn get_version(&self) -> Result<ServerVersion, ForgejoError> { + let request = self.get("version").build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } +} diff --git a/src/generated/mod.rs b/src/generated/mod.rs new file mode 100644 index 0000000..fb6927b --- /dev/null +++ b/src/generated/mod.rs @@ -0,0 +1,2 @@ +pub mod methods; +pub mod structs; diff --git a/src/generated/structs.rs b/src/generated/structs.rs new file mode 100644 index 0000000..b99c2a0 --- /dev/null +++ b/src/generated/structs.rs @@ -0,0 +1,6487 @@ +use crate::StructureError; +use std::collections::BTreeMap; +/// APIError is an api error with a message +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct APIError { + pub message: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct AccessToken { + pub id: Option<i64>, + pub name: Option<String>, + pub scopes: Option<Vec<String>>, + pub sha1: Option<String>, + pub token_last_eight: Option<String>, +} + +/// ActionTask represents a ActionTask +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ActionTask { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub display_title: Option<String>, + pub event: Option<String>, + pub head_branch: Option<String>, + pub head_sha: Option<String>, + pub id: Option<i64>, + pub name: Option<String>, + pub run_number: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub run_started_at: Option<time::OffsetDateTime>, + pub status: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub workflow_id: Option<String>, +} + +/// ActionTaskResponse returns a ActionTask +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ActionTaskResponse { + pub total_count: Option<i64>, + pub workflow_runs: Option<Vec<ActionTask>>, +} + +/// ActionVariable return value of the query API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ActionVariable { + /// the value of the variable + pub data: Option<String>, + /// the name of the variable + pub name: Option<String>, + /// the owner to which the variable belongs + pub owner_id: Option<i64>, + /// the repository to which the variable belongs + pub repo_id: Option<i64>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Activity { + pub act_user: Option<User>, + pub act_user_id: Option<i64>, + pub comment: Option<Comment>, + pub comment_id: Option<i64>, + pub content: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub is_private: Option<bool>, + /// the type of action + pub op_type: Option<ActivityOpType>, + pub ref_name: Option<String>, + pub repo: Option<Repository>, + pub repo_id: Option<i64>, + pub user_id: Option<i64>, +} + +/// the type of action + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum ActivityOpType { + #[serde(rename = "create_repo")] + CreateRepo, + #[serde(rename = "rename_repo")] + RenameRepo, + #[serde(rename = "star_repo")] + StarRepo, + #[serde(rename = "watch_repo")] + WatchRepo, + #[serde(rename = "commit_repo")] + CommitRepo, + #[serde(rename = "create_issue")] + CreateIssue, + #[serde(rename = "create_pull_request")] + CreatePullRequest, + #[serde(rename = "transfer_repo")] + TransferRepo, + #[serde(rename = "push_tag")] + PushTag, + #[serde(rename = "comment_issue")] + CommentIssue, + #[serde(rename = "merge_pull_request")] + MergePullRequest, + #[serde(rename = "close_issue")] + CloseIssue, + #[serde(rename = "reopen_issue")] + ReopenIssue, + #[serde(rename = "close_pull_request")] + ClosePullRequest, + #[serde(rename = "reopen_pull_request")] + ReopenPullRequest, + #[serde(rename = "delete_tag")] + DeleteTag, + #[serde(rename = "delete_branch")] + DeleteBranch, + #[serde(rename = "mirror_sync_push")] + MirrorSyncPush, + #[serde(rename = "mirror_sync_create")] + MirrorSyncCreate, + #[serde(rename = "mirror_sync_delete")] + MirrorSyncDelete, + #[serde(rename = "approve_pull_request")] + ApprovePullRequest, + #[serde(rename = "reject_pull_request")] + RejectPullRequest, + #[serde(rename = "comment_pull")] + CommentPull, + #[serde(rename = "publish_release")] + PublishRelease, + #[serde(rename = "pull_review_dismissed")] + PullReviewDismissed, + #[serde(rename = "pull_request_ready_for_review")] + PullRequestReadyForReview, + #[serde(rename = "auto_merge_pull_request")] + AutoMergePullRequest, +} +/// ActivityPub type +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ActivityPub { + #[serde(rename = "@context")] + pub context: Option<String>, +} + +/// AddCollaboratorOption options when adding a user as a collaborator of a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct AddCollaboratorOption { + pub permission: Option<String>, +} + +/// AddTimeOption options for adding time to an issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct AddTimeOption { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + /// time in seconds + pub time: i64, + /// User who spent the time (optional) + pub user_name: Option<String>, +} + +/// AnnotatedTag represents an annotated tag +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct AnnotatedTag { + pub archive_download_count: Option<TagArchiveDownloadCount>, + pub message: Option<String>, + pub object: Option<AnnotatedTagObject>, + pub sha: Option<String>, + pub tag: Option<String>, + pub tagger: Option<CommitUser>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub verification: Option<PayloadCommitVerification>, +} + +/// AnnotatedTagObject contains meta information of the tag object +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct AnnotatedTagObject { + pub sha: Option<String>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// Attachment a generic attachment +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Attachment { + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub browser_download_url: Option<url::Url>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub download_count: Option<i64>, + pub id: Option<i64>, + pub name: Option<String>, + pub size: Option<i64>, + pub uuid: Option<String>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BlockedUser { + pub block_id: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, +} + +/// Branch represents a repository branch +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Branch { + pub commit: Option<PayloadCommit>, + pub effective_branch_protection_name: Option<String>, + pub enable_status_check: Option<bool>, + pub name: Option<String>, + pub protected: Option<bool>, + pub required_approvals: Option<i64>, + pub status_check_contexts: Option<Vec<String>>, + pub user_can_merge: Option<bool>, + pub user_can_push: Option<bool>, +} + +/// BranchProtection represents a branch protection for a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct BranchProtection { + pub apply_to_admins: Option<bool>, + pub approvals_whitelist_teams: Option<Vec<String>>, + pub approvals_whitelist_username: Option<Vec<String>>, + pub block_on_official_review_requests: Option<bool>, + pub block_on_outdated_branch: Option<bool>, + pub block_on_rejected_reviews: Option<bool>, + /// Deprecated: true + pub branch_name: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub dismiss_stale_approvals: Option<bool>, + pub enable_approvals_whitelist: Option<bool>, + pub enable_merge_whitelist: Option<bool>, + pub enable_push: Option<bool>, + pub enable_push_whitelist: Option<bool>, + pub enable_status_check: Option<bool>, + pub ignore_stale_approvals: Option<bool>, + pub merge_whitelist_teams: Option<Vec<String>>, + pub merge_whitelist_usernames: Option<Vec<String>>, + pub protected_file_patterns: Option<String>, + pub push_whitelist_deploy_keys: Option<bool>, + pub push_whitelist_teams: Option<Vec<String>>, + pub push_whitelist_usernames: Option<Vec<String>>, + pub require_signed_commits: Option<bool>, + pub required_approvals: Option<i64>, + pub rule_name: Option<String>, + pub status_check_contexts: Option<Vec<String>>, + pub unprotected_file_patterns: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// ChangeFileOperation for creating, updating or deleting a file +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ChangeFileOperation { + /// new or updated file content, must be base64 encoded + pub content: Option<String>, + /// old path of the file to move + pub from_path: Option<String>, + /// indicates what to do with the file + pub operation: ChangeFileOperationOperation, + /// path to the existing or new file + pub path: String, + /// sha is the SHA for the file that already exists, required for update or delete + pub sha: Option<String>, +} + +/// indicates what to do with the file + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum ChangeFileOperationOperation { + #[serde(rename = "create")] + Create, + #[serde(rename = "update")] + Update, + #[serde(rename = "delete")] + Delete, +} +/// ChangeFilesOptions options for creating, updating or deleting multiple 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) +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ChangeFilesOptions { + pub author: Option<Identity>, + /// branch (optional) to base this file from. if not given, the default branch is used + pub branch: Option<String>, + pub committer: Option<Identity>, + pub dates: Option<CommitDateOptions>, + /// list of file operations + pub files: Vec<ChangeFileOperation>, + /// message (optional) for the commit of this file. if not supplied, a default message will be used + pub message: Option<String>, + /// new_branch (optional) will make a new branch from `branch` before creating the file + pub new_branch: Option<String>, + /// Add a Signed-off-by trailer by the committer at the end of the commit log message. + pub signoff: Option<bool>, +} + +/// ChangedFile store information about files affected by the pull request +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ChangedFile { + pub additions: Option<i64>, + pub changes: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub contents_url: Option<url::Url>, + pub deletions: Option<i64>, + pub filename: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub previous_filename: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub raw_url: Option<url::Url>, + pub status: Option<String>, +} + +/// CombinedStatus holds the combined state of several statuses for a single commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CombinedStatus { + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub commit_url: Option<url::Url>, + pub repository: Option<Repository>, + pub sha: Option<String>, + pub state: Option<String>, + pub statuses: Option<Vec<CommitStatus>>, + pub total_count: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// Comment represents a comment on a commit or issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Comment { + pub assets: Option<Vec<Attachment>>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub issue_url: Option<url::Url>, + pub original_author: Option<String>, + pub original_author_id: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub pull_request_url: Option<url::Url>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + pub user: Option<User>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Commit { + pub author: Option<User>, + pub commit: Option<RepoCommit>, + pub committer: Option<User>, + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub files: Option<Vec<CommitAffectedFiles>>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub parents: Option<Vec<CommitMeta>>, + pub sha: Option<String>, + pub stats: Option<CommitStats>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// CommitAffectedFiles store information about files affected by the commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitAffectedFiles { + pub filename: Option<String>, + pub status: Option<String>, +} + +/// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitDateOptions { + #[serde(with = "time::serde::rfc3339::option")] + pub author: Option<time::OffsetDateTime>, + #[serde(with = "time::serde::rfc3339::option")] + pub committer: Option<time::OffsetDateTime>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitMeta { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub sha: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// CommitStats is statistics for a RepoCommit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitStats { + pub additions: Option<i64>, + pub deletions: Option<i64>, + pub total: Option<i64>, +} + +/// CommitStatus holds a single status of a single Commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitStatus { + pub context: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub creator: Option<User>, + pub description: Option<String>, + pub id: Option<i64>, + pub status: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub target_url: Option<url::Url>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// CommitStatusState holds the state of a CommitStatus +/// +/// It can be "pending", "success", "error" and "failure" +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitStatusState {} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CommitUser { + pub date: Option<String>, + pub email: Option<String>, + pub name: Option<String>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Compare { + pub commits: Option<Vec<Commit>>, + pub total_commits: Option<i64>, +} + +/// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ContentsResponse { + #[serde(rename = "_links")] + pub links: Option<FileLinksResponse>, + /// `content` is populated when `type` is `file`, otherwise null + pub content: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub download_url: Option<url::Url>, + /// `encoding` is populated when `type` is `file`, otherwise null + pub encoding: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub git_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub last_commit_sha: Option<String>, + pub name: Option<String>, + pub path: Option<String>, + pub sha: Option<String>, + pub size: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + /// `submodule_git_url` is populated when `type` is `submodule`, otherwise null + pub submodule_git_url: Option<url::Url>, + /// `target` is populated when `type` is `symlink`, otherwise null + pub target: Option<String>, + /// `type` will be `file`, `dir`, `symlink`, or `submodule` + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// CreateAccessTokenOption options when create access token +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateAccessTokenOption { + pub name: String, + pub scopes: Option<Vec<String>>, +} + +/// CreateBranchProtectionOption options for creating a branch protection +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateBranchProtectionOption { + pub apply_to_admins: Option<bool>, + pub approvals_whitelist_teams: Option<Vec<String>>, + pub approvals_whitelist_username: Option<Vec<String>>, + pub block_on_official_review_requests: Option<bool>, + pub block_on_outdated_branch: Option<bool>, + pub block_on_rejected_reviews: Option<bool>, + /// Deprecated: true + pub branch_name: Option<String>, + pub dismiss_stale_approvals: Option<bool>, + pub enable_approvals_whitelist: Option<bool>, + pub enable_merge_whitelist: Option<bool>, + pub enable_push: Option<bool>, + pub enable_push_whitelist: Option<bool>, + pub enable_status_check: Option<bool>, + pub ignore_stale_approvals: Option<bool>, + pub merge_whitelist_teams: Option<Vec<String>>, + pub merge_whitelist_usernames: Option<Vec<String>>, + pub protected_file_patterns: Option<String>, + pub push_whitelist_deploy_keys: Option<bool>, + pub push_whitelist_teams: Option<Vec<String>>, + pub push_whitelist_usernames: Option<Vec<String>>, + pub require_signed_commits: Option<bool>, + pub required_approvals: Option<i64>, + pub rule_name: Option<String>, + pub status_check_contexts: Option<Vec<String>>, + pub unprotected_file_patterns: Option<String>, +} + +/// CreateBranchRepoOption options when creating a branch in a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateBranchRepoOption { + /// Name of the branch to create + pub new_branch_name: String, + /// Deprecated: true + /// + /// Name of the old branch to create from + pub old_branch_name: Option<String>, + /// Name of the old branch/tag/commit to create from + pub old_ref_name: Option<String>, +} + +/// CreateEmailOption options when creating email addresses +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateEmailOption { + /// email addresses to add + pub emails: Option<Vec<String>>, +} + +/// 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) +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateFileOptions { + pub author: Option<Identity>, + /// branch (optional) to base this file from. if not given, the default branch is used + pub branch: Option<String>, + pub committer: Option<Identity>, + /// content must be base64 encoded + pub content: String, + pub dates: Option<CommitDateOptions>, + /// message (optional) for the commit of this file. if not supplied, a default message will be used + pub message: Option<String>, + /// new_branch (optional) will make a new branch from `branch` before creating the file + pub new_branch: Option<String>, + /// Add a Signed-off-by trailer by the committer at the end of the commit log message. + pub signoff: Option<bool>, +} + +/// CreateForkOption options for creating a fork +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateForkOption { + /// name of the forked repository + pub name: Option<String>, + /// organization name, if forking into an organization + pub organization: Option<String>, +} + +/// CreateGPGKeyOption options create user GPG key +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateGPGKeyOption { + /// An armored GPG key to add + pub armored_public_key: String, + pub armored_signature: Option<String>, +} + +/// CreateHookOption options when create a hook +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateHookOption { + pub active: Option<bool>, + pub authorization_header: Option<String>, + pub branch_filter: Option<String>, + pub config: CreateHookOptionConfig, + pub events: Option<Vec<String>>, + #[serde(rename = "type")] + pub r#type: CreateHookOptionType, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum CreateHookOptionType { + #[serde(rename = "forgejo")] + Forgejo, + #[serde(rename = "dingtalk")] + Dingtalk, + #[serde(rename = "discord")] + Discord, + #[serde(rename = "gitea")] + Gitea, + #[serde(rename = "gogs")] + Gogs, + #[serde(rename = "msteams")] + Msteams, + #[serde(rename = "slack")] + Slack, + #[serde(rename = "telegram")] + Telegram, + #[serde(rename = "feishu")] + Feishu, + #[serde(rename = "wechatwork")] + Wechatwork, + #[serde(rename = "packagist")] + Packagist, +} +/// CreateHookOptionConfig has all config options in it +/// +/// required are "content_type" and "url" Required +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateHookOptionConfig { + pub content_type: String, + pub url: url::Url, + #[serde(flatten)] + pub additional: BTreeMap<String, String>, +} + +/// CreateIssueCommentOption options for creating a comment on an issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateIssueCommentOption { + pub body: String, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// CreateIssueOption options to create one issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateIssueOption { + /// deprecated + pub assignee: Option<String>, + pub assignees: Option<Vec<String>>, + pub body: Option<String>, + pub closed: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + /// list of label ids + pub labels: Option<Vec<i64>>, + /// milestone id + pub milestone: Option<i64>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + pub title: String, +} + +/// CreateKeyOption options when creating a key +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateKeyOption { + /// An armored SSH key to add + pub key: String, + /// Describe if the key has only read access or read/write + pub read_only: Option<bool>, + /// Title of the key to add + pub title: String, +} + +/// CreateLabelOption options for creating a label +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateLabelOption { + pub color: String, + pub description: Option<String>, + pub exclusive: Option<bool>, + pub is_archived: Option<bool>, + pub name: String, +} + +/// CreateMilestoneOption options for creating a milestone +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateMilestoneOption { + pub description: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_on: Option<time::OffsetDateTime>, + pub state: Option<CreateMilestoneOptionState>, + pub title: Option<String>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum CreateMilestoneOptionState { + #[serde(rename = "open")] + Open, + #[serde(rename = "closed")] + Closed, +} +/// CreateOAuth2ApplicationOptions holds options to create an oauth2 application +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateOAuth2ApplicationOptions { + pub confidential_client: Option<bool>, + pub name: Option<String>, + pub redirect_uris: Option<Vec<String>>, +} + +/// CreateOrUpdateSecretOption options when creating or updating secret +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateOrUpdateSecretOption { + /// Data of the secret to update + pub data: String, +} + +/// CreateOrgOption options for creating an organization +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateOrgOption { + pub description: Option<String>, + pub email: Option<String>, + pub full_name: Option<String>, + pub location: Option<String>, + pub repo_admin_change_team_access: Option<bool>, + pub username: String, + /// possible values are `public` (default), `limited` or `private` + pub visibility: Option<CreateOrgOptionVisibility>, + pub website: Option<String>, +} + +/// possible values are `public` (default), `limited` or `private` + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum CreateOrgOptionVisibility { + #[serde(rename = "public")] + Public, + #[serde(rename = "limited")] + Limited, + #[serde(rename = "private")] + Private, +} +/// CreatePullRequestOption options when creating a pull request +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreatePullRequestOption { + pub assignee: Option<String>, + pub assignees: Option<Vec<String>>, + pub base: Option<String>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + pub head: Option<String>, + pub labels: Option<Vec<i64>>, + pub milestone: Option<i64>, + pub title: Option<String>, +} + +/// CreatePullReviewComment represent a review comment for creation api +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreatePullReviewComment { + pub body: Option<String>, + /// if comment to new file line or 0 + pub new_position: Option<i64>, + /// if comment to old file line or 0 + pub old_position: Option<i64>, + /// the tree path + pub path: Option<String>, +} + +/// CreatePullReviewCommentOptions are options to create a pull review comment +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreatePullReviewCommentOptions {} + +/// CreatePullReviewOptions are options to create a pull review +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreatePullReviewOptions { + pub body: Option<String>, + pub comments: Option<Vec<CreatePullReviewComment>>, + pub commit_id: Option<String>, + pub event: Option<String>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreatePushMirrorOption { + pub interval: Option<String>, + pub remote_address: Option<String>, + pub remote_password: Option<String>, + pub remote_username: Option<String>, + pub sync_on_commit: Option<bool>, +} + +/// CreateReleaseOption options when creating a release +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateReleaseOption { + pub body: Option<String>, + pub draft: Option<bool>, + pub hide_archive_links: Option<bool>, + pub name: Option<String>, + pub prerelease: Option<bool>, + pub tag_name: String, + pub target_commitish: Option<String>, +} + +/// CreateRepoOption options when creating repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateRepoOption { + /// Whether the repository should be auto-initialized? + pub auto_init: Option<bool>, + /// DefaultBranch of the repository (used when initializes and in template) + pub default_branch: Option<String>, + /// Description of the repository to create + pub description: Option<String>, + /// Gitignores to use + pub gitignores: Option<String>, + /// Label-Set to use + pub issue_labels: Option<String>, + /// License to use + pub license: Option<String>, + /// Name of the repository to create + pub name: String, + pub object_format_name: Option<ObjectFormatName>, + /// Whether the repository is private + pub private: Option<bool>, + /// Readme of the repository to create + pub readme: Option<String>, + /// Whether the repository is template + pub template: Option<bool>, + /// TrustModel of the repository + pub trust_model: Option<CreateRepoOptionTrustModel>, +} + +/// TrustModel of the repository + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum CreateRepoOptionTrustModel { + #[serde(rename = "default")] + Default, + #[serde(rename = "collaborator")] + Collaborator, + #[serde(rename = "committer")] + Committer, + #[serde(rename = "collaboratorcommitter")] + Collaboratorcommitter, +} +/// CreateStatusOption holds the information needed to create a new CommitStatus for a Commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateStatusOption { + pub context: Option<String>, + pub description: Option<String>, + pub state: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub target_url: Option<url::Url>, +} + +/// CreateTagOption options when creating a tag +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateTagOption { + pub message: Option<String>, + pub tag_name: String, + pub target: Option<String>, +} + +/// CreateTagProtectionOption options for creating a tag protection +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateTagProtectionOption { + pub name_pattern: Option<String>, + pub whitelist_teams: Option<Vec<String>>, + pub whitelist_usernames: Option<Vec<String>>, +} + +/// CreateTeamOption options for creating a team +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateTeamOption { + pub can_create_org_repo: Option<bool>, + pub description: Option<String>, + pub includes_all_repositories: Option<bool>, + pub name: String, + pub permission: Option<CreateTeamOptionPermission>, + pub units: Option<Vec<String>>, + pub units_map: Option<BTreeMap<String, String>>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum CreateTeamOptionPermission { + #[serde(rename = "read")] + Read, + #[serde(rename = "write")] + Write, + #[serde(rename = "admin")] + Admin, +} +/// CreateUserOption create user options +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateUserOption { + #[serde(with = "time::serde::rfc3339::option")] + /// For explicitly setting the user creation timestamp. Useful when users are + /// + /// migrated from other systems. When omitted, the user's creation timestamp + /// + /// will be set to "now". + pub created_at: Option<time::OffsetDateTime>, + pub email: String, + pub full_name: Option<String>, + pub login_name: Option<String>, + pub must_change_password: Option<bool>, + pub password: Option<String>, + pub restricted: Option<bool>, + pub send_notify: Option<bool>, + pub source_id: Option<i64>, + pub username: String, + pub visibility: Option<String>, +} + +/// CreateVariableOption the option when creating variable +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateVariableOption { + /// Value of the variable to create + pub value: String, +} + +/// CreateWikiPageOptions form for creating wiki +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct CreateWikiPageOptions { + /// content must be base64 encoded + pub content_base64: Option<String>, + /// optional commit message summarizing the change + pub message: Option<String>, + /// page title. leave empty to keep unchanged + pub title: Option<String>, +} + +/// Cron represents a Cron task +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Cron { + pub exec_times: Option<i64>, + pub name: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub next: Option<time::OffsetDateTime>, + #[serde(with = "time::serde::rfc3339::option")] + pub prev: Option<time::OffsetDateTime>, + pub schedule: Option<String>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum DefaultMergeStyle { + #[serde(rename = "merge")] + Merge, + #[serde(rename = "rebase")] + Rebase, + #[serde(rename = "rebase-merge")] + RebaseMerge, + #[serde(rename = "squash")] + Squash, + #[serde(rename = "fast-forward-only")] + FastForwardOnly, +} +/// DeleteEmailOption options when deleting email addresses +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DeleteEmailOption { + /// email addresses to delete + pub emails: Option<Vec<String>>, +} + +/// 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) +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DeleteFileOptions { + pub author: Option<Identity>, + /// branch (optional) to base this file from. if not given, the default branch is used + pub branch: Option<String>, + pub committer: Option<Identity>, + pub dates: Option<CommitDateOptions>, + /// message (optional) for the commit of this file. if not supplied, a default message will be used + pub message: Option<String>, + /// new_branch (optional) will make a new branch from `branch` before creating the file + pub new_branch: Option<String>, + /// sha is the SHA for the file that already exists + pub sha: String, + /// Add a Signed-off-by trailer by the committer at the end of the commit log message. + pub signoff: Option<bool>, +} + +/// DeleteLabelOption options for deleting a label +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DeleteLabelsOption { + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// DeployKey a deploy key +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DeployKey { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub fingerprint: Option<String>, + pub id: Option<i64>, + pub key: Option<String>, + pub key_id: Option<i64>, + pub read_only: Option<bool>, + pub repository: Option<Repository>, + pub title: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// DismissPullReviewOptions are options to dismiss a pull review +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DismissPullReviewOptions { + pub message: Option<String>, + pub priors: Option<bool>, +} + +/// DispatchWorkflowOption options when dispatching a workflow +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct DispatchWorkflowOption { + /// Input keys and values configured in the workflow file. + pub inputs: Option<BTreeMap<String, String>>, + /// Git reference for the workflow + #[serde(rename = "ref")] + pub r#ref: String, +} + +/// EditAttachmentOptions options for editing attachments +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditAttachmentOptions { + pub name: Option<String>, +} + +/// EditBranchProtectionOption options for editing a branch protection +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditBranchProtectionOption { + pub apply_to_admins: Option<bool>, + pub approvals_whitelist_teams: Option<Vec<String>>, + pub approvals_whitelist_username: Option<Vec<String>>, + pub block_on_official_review_requests: Option<bool>, + pub block_on_outdated_branch: Option<bool>, + pub block_on_rejected_reviews: Option<bool>, + pub dismiss_stale_approvals: Option<bool>, + pub enable_approvals_whitelist: Option<bool>, + pub enable_merge_whitelist: Option<bool>, + pub enable_push: Option<bool>, + pub enable_push_whitelist: Option<bool>, + pub enable_status_check: Option<bool>, + pub ignore_stale_approvals: Option<bool>, + pub merge_whitelist_teams: Option<Vec<String>>, + pub merge_whitelist_usernames: Option<Vec<String>>, + pub protected_file_patterns: Option<String>, + pub push_whitelist_deploy_keys: Option<bool>, + pub push_whitelist_teams: Option<Vec<String>>, + pub push_whitelist_usernames: Option<Vec<String>>, + pub require_signed_commits: Option<bool>, + pub required_approvals: Option<i64>, + pub status_check_contexts: Option<Vec<String>>, + pub unprotected_file_patterns: Option<String>, +} + +/// EditDeadlineOption options for creating a deadline +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditDeadlineOption { + #[serde(with = "time::serde::rfc3339")] + pub due_date: time::OffsetDateTime, +} + +/// EditGitHookOption options when modifying one Git hook +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditGitHookOption { + pub content: Option<String>, +} + +/// EditHookOption options when modify one hook +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditHookOption { + pub active: Option<bool>, + pub authorization_header: Option<String>, + pub branch_filter: Option<String>, + pub config: Option<BTreeMap<String, String>>, + pub events: Option<Vec<String>>, +} + +/// EditIssueCommentOption options for editing a comment +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditIssueCommentOption { + pub body: String, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// EditIssueOption options for editing an issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditIssueOption { + /// deprecated + pub assignee: Option<String>, + pub assignees: Option<Vec<String>>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + pub milestone: Option<i64>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + pub state: Option<String>, + pub title: Option<String>, + pub unset_due_date: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// EditLabelOption options for editing a label +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditLabelOption { + pub color: Option<String>, + pub description: Option<String>, + pub exclusive: Option<bool>, + pub is_archived: Option<bool>, + pub name: Option<String>, +} + +/// EditMilestoneOption options for editing a milestone +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditMilestoneOption { + pub description: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_on: Option<time::OffsetDateTime>, + pub state: Option<String>, + pub title: Option<String>, +} + +/// EditOrgOption options for editing an organization +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditOrgOption { + pub description: Option<String>, + pub email: Option<String>, + pub full_name: Option<String>, + pub location: Option<String>, + pub repo_admin_change_team_access: Option<bool>, + /// possible values are `public`, `limited` or `private` + pub visibility: Option<EditOrgOptionVisibility>, + pub website: Option<String>, +} + +/// possible values are `public`, `limited` or `private` + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum EditOrgOptionVisibility { + #[serde(rename = "public")] + Public, + #[serde(rename = "limited")] + Limited, + #[serde(rename = "private")] + Private, +} +/// EditPullRequestOption options when modify pull request +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditPullRequestOption { + pub allow_maintainer_edit: Option<bool>, + pub assignee: Option<String>, + pub assignees: Option<Vec<String>>, + pub base: Option<String>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + pub labels: Option<Vec<i64>>, + pub milestone: Option<i64>, + pub state: Option<String>, + pub title: Option<String>, + pub unset_due_date: Option<bool>, +} + +/// EditReactionOption contain the reaction type +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditReactionOption { + pub content: Option<String>, +} + +/// EditReleaseOption options when editing a release +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditReleaseOption { + pub body: Option<String>, + pub draft: Option<bool>, + pub hide_archive_links: Option<bool>, + pub name: Option<String>, + pub prerelease: Option<bool>, + pub tag_name: Option<String>, + pub target_commitish: Option<String>, +} + +/// EditRepoOption options when editing a repository's properties +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditRepoOption { + /// either `true` to allow fast-forward-only merging pull requests, or `false` to prevent fast-forward-only merging. + pub allow_fast_forward_only_merge: Option<bool>, + /// either `true` to allow mark pr as merged manually, or `false` to prevent it. + pub allow_manual_merge: Option<bool>, + /// either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits. + pub allow_merge_commits: Option<bool>, + /// either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging. + pub allow_rebase: Option<bool>, + /// either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits. + pub allow_rebase_explicit: Option<bool>, + /// either `true` to allow updating pull request branch by rebase, or `false` to prevent it. + pub allow_rebase_update: Option<bool>, + /// either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging. + pub allow_squash_merge: Option<bool>, + /// set to `true` to archive this repository. + pub archived: Option<bool>, + /// either `true` to enable AutodetectManualMerge, or `false` to prevent it. Note: In some special cases, misjudgments can occur. + pub autodetect_manual_merge: Option<bool>, + /// set to `true` to allow edits from maintainers by default + pub default_allow_maintainer_edit: Option<bool>, + /// sets the default branch for this repository. + pub default_branch: Option<String>, + /// set to `true` to delete pr branch after merge by default + pub default_delete_branch_after_merge: Option<bool>, + pub default_merge_style: Option<DefaultMergeStyle>, + /// a short description of the repository. + pub description: Option<String>, + /// enable prune - remove obsolete remote-tracking references when mirroring + pub enable_prune: Option<bool>, + pub external_tracker: Option<ExternalTracker>, + pub external_wiki: Option<ExternalWiki>, + /// set the globally editable state of the wiki + pub globally_editable_wiki: Option<bool>, + /// either `true` to enable actions unit, or `false` to disable them. + pub has_actions: Option<bool>, + /// either `true` to enable issues for this repository or `false` to disable them. + pub has_issues: Option<bool>, + /// either `true` to enable packages unit, or `false` to disable them. + pub has_packages: Option<bool>, + /// either `true` to enable project unit, or `false` to disable them. + pub has_projects: Option<bool>, + /// either `true` to allow pull requests, or `false` to prevent pull request. + pub has_pull_requests: Option<bool>, + /// either `true` to enable releases unit, or `false` to disable them. + pub has_releases: Option<bool>, + /// either `true` to enable the wiki for this repository or `false` to disable it. + pub has_wiki: Option<bool>, + /// either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace. + pub ignore_whitespace_conflicts: Option<bool>, + pub internal_tracker: Option<InternalTracker>, + /// set to a string like `8h30m0s` to set the mirror interval time + pub mirror_interval: Option<String>, + /// name of the repository + pub name: Option<String>, + /// either `true` to make the repository private or `false` to make it public. + /// + /// Note: you will get a 422 error if the organization restricts changing repository visibility to organization + /// + /// owners and a non-owner tries to change the value of private. + pub private: Option<bool>, + /// either `true` to make this repository a template or `false` to make it a normal repository + pub template: Option<bool>, + /// a URL with more information about the repository. + pub website: Option<String>, + /// sets the branch used for this repository's wiki. + pub wiki_branch: Option<String>, +} + +/// EditTagProtectionOption options for editing a tag protection +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditTagProtectionOption { + pub name_pattern: Option<String>, + pub whitelist_teams: Option<Vec<String>>, + pub whitelist_usernames: Option<Vec<String>>, +} + +/// EditTeamOption options for editing a team +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditTeamOption { + pub can_create_org_repo: Option<bool>, + pub description: Option<String>, + pub includes_all_repositories: Option<bool>, + pub name: String, + pub permission: Option<EditTeamOptionPermission>, + pub units: Option<Vec<String>>, + pub units_map: Option<BTreeMap<String, String>>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum EditTeamOptionPermission { + #[serde(rename = "read")] + Read, + #[serde(rename = "write")] + Write, + #[serde(rename = "admin")] + Admin, +} +/// EditUserOption edit user options +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct EditUserOption { + pub active: Option<bool>, + pub admin: Option<bool>, + pub allow_create_organization: Option<bool>, + pub allow_git_hook: Option<bool>, + pub allow_import_local: Option<bool>, + pub description: Option<String>, + pub email: Option<String>, + pub full_name: Option<String>, + pub location: Option<String>, + pub login_name: Option<String>, + pub max_repo_creation: Option<i64>, + pub must_change_password: Option<bool>, + pub password: Option<String>, + pub prohibit_login: Option<bool>, + pub pronouns: Option<String>, + pub restricted: Option<bool>, + pub source_id: Option<i64>, + pub visibility: Option<String>, + pub website: Option<String>, +} + +/// Email an email address belonging to a user +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Email { + pub email: Option<String>, + pub primary: Option<bool>, + pub user_id: Option<i64>, + pub username: Option<String>, + pub verified: Option<bool>, +} + +/// ExternalTracker represents settings for external tracker +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ExternalTracker { + /// External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index. + pub external_tracker_format: Option<String>, + /// External Issue Tracker issue regular expression + pub external_tracker_regexp_pattern: Option<String>, + /// External Issue Tracker Number Format, either `numeric`, `alphanumeric`, or `regexp` + pub external_tracker_style: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + /// URL of external issue tracker. + pub external_tracker_url: Option<url::Url>, +} + +/// ExternalWiki represents setting for external wiki +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ExternalWiki { + #[serde(deserialize_with = "crate::none_if_blank_url")] + /// URL of external wiki. + pub external_wiki_url: Option<url::Url>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FileCommitResponse { + pub author: Option<CommitUser>, + pub committer: Option<CommitUser>, + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub message: Option<String>, + pub parents: Option<Vec<CommitMeta>>, + pub sha: Option<String>, + pub tree: Option<CommitMeta>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// FileDeleteResponse contains information about a repo's file that was deleted +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FileDeleteResponse { + pub commit: Option<FileCommitResponse>, + pub content: Option<serde_json::Value>, + pub verification: Option<PayloadCommitVerification>, +} + +/// FileLinksResponse contains the links for a repo's file +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FileLinksResponse { + pub git: Option<String>, + pub html: Option<String>, + #[serde(rename = "self")] + pub this: Option<String>, +} + +/// FileResponse contains information about a repo's file +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FileResponse { + pub commit: Option<FileCommitResponse>, + pub content: Option<ContentsResponse>, + pub verification: Option<PayloadCommitVerification>, +} + +/// FilesResponse contains information about multiple files from a repo +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct FilesResponse { + pub commit: Option<FileCommitResponse>, + pub files: Option<Vec<ContentsResponse>>, + pub verification: Option<PayloadCommitVerification>, +} + +/// ForgeLike activity data type +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ForgeLike {} + +/// GPGKey a user GPG key to sign commit and tag in repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GPGKey { + pub can_certify: Option<bool>, + pub can_encrypt_comms: Option<bool>, + pub can_encrypt_storage: Option<bool>, + pub can_sign: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub emails: Option<Vec<GPGKeyEmail>>, + #[serde(with = "time::serde::rfc3339::option")] + pub expires_at: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub key_id: Option<String>, + pub primary_key_id: Option<String>, + pub public_key: Option<String>, + pub subkeys: Option<Vec<GPGKey>>, + pub verified: Option<bool>, +} + +/// GPGKeyEmail an email attached to a GPGKey +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GPGKeyEmail { + pub email: Option<String>, + pub verified: Option<bool>, +} + +/// GeneralAPISettings contains global api settings exposed by it +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GeneralAPISettings { + pub default_git_trees_per_page: Option<i64>, + pub default_max_blob_size: Option<i64>, + pub default_paging_num: Option<i64>, + pub max_response_items: Option<i64>, +} + +/// GeneralAttachmentSettings contains global Attachment settings exposed by API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GeneralAttachmentSettings { + pub allowed_types: Option<String>, + pub enabled: Option<bool>, + pub max_files: Option<i64>, + pub max_size: Option<i64>, +} + +/// GeneralRepoSettings contains global repository settings exposed by API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GeneralRepoSettings { + pub forks_disabled: Option<bool>, + pub http_git_disabled: Option<bool>, + pub lfs_disabled: Option<bool>, + pub migrations_disabled: Option<bool>, + pub mirrors_disabled: Option<bool>, + pub stars_disabled: Option<bool>, + pub time_tracking_disabled: Option<bool>, +} + +/// GeneralUISettings contains global ui settings exposed by API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GeneralUISettings { + pub allowed_reactions: Option<Vec<String>>, + pub custom_emojis: Option<Vec<String>>, + pub default_theme: Option<String>, +} + +/// GenerateRepoOption options when creating repository using a template +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GenerateRepoOption { + /// include avatar of the template repo + pub avatar: Option<bool>, + /// Default branch of the new repository + pub default_branch: Option<String>, + /// Description of the repository to create + pub description: Option<String>, + /// include git content of default branch in template repo + pub git_content: Option<bool>, + /// include git hooks in template repo + pub git_hooks: Option<bool>, + /// include labels in template repo + pub labels: Option<bool>, + /// Name of the repository to create + pub name: String, + /// The organization or person who will own the new repository + pub owner: String, + /// Whether the repository is private + pub private: Option<bool>, + /// include protected branches in template repo + pub protected_branch: Option<bool>, + /// include topics in template repo + pub topics: Option<bool>, + /// include webhooks in template repo + pub webhooks: Option<bool>, +} + +/// GitBlobResponse represents a git blob +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitBlobResponse { + pub content: Option<String>, + pub encoding: Option<String>, + pub sha: Option<String>, + pub size: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// GitEntry represents a git tree +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitEntry { + pub mode: Option<String>, + pub path: Option<String>, + pub sha: Option<String>, + pub size: Option<i64>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// GitHook represents a Git repository hook +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitHook { + pub content: Option<String>, + pub is_active: Option<bool>, + pub name: Option<String>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitObject { + pub sha: Option<String>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// GitTreeResponse returns a git tree +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitTreeResponse { + pub page: Option<i64>, + pub sha: Option<String>, + pub total_count: Option<i64>, + pub tree: Option<Vec<GitEntry>>, + pub truncated: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// GitignoreTemplateInfo name and text of a gitignore template +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct GitignoreTemplateInfo { + pub name: Option<String>, + pub source: Option<String>, +} + +/// Hook a hook is a web hook when one repository changed +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Hook { + pub active: Option<bool>, + pub authorization_header: Option<String>, + pub branch_filter: Option<String>, + /// Deprecated: use Metadata instead + pub config: Option<BTreeMap<String, String>>, + pub content_type: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub events: Option<Vec<String>>, + pub id: Option<i64>, + pub metadata: Option<serde_json::Value>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// Identity for a person's identity like an author or committer +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Identity { + pub email: Option<String>, + pub name: Option<String>, +} + +/// InternalTracker represents settings for internal tracker +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct InternalTracker { + /// Let only contributors track time (Built-in issue tracker) + pub allow_only_contributors_to_track_time: Option<bool>, + /// Enable dependencies for issues and pull requests (Built-in issue tracker) + pub enable_issue_dependencies: Option<bool>, + /// Enable time tracking (Built-in issue tracker) + pub enable_time_tracker: Option<bool>, +} + +/// Issue represents an issue in a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Issue { + pub assets: Option<Vec<Attachment>>, + pub assignee: Option<User>, + pub assignees: Option<Vec<User>>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub closed_at: Option<time::OffsetDateTime>, + pub comments: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub is_locked: Option<bool>, + pub labels: Option<Vec<Label>>, + pub milestone: Option<Milestone>, + pub number: Option<i64>, + pub original_author: Option<String>, + pub original_author_id: Option<i64>, + pub pin_order: Option<i64>, + pub pull_request: Option<PullRequestMeta>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + pub repository: Option<RepositoryMeta>, + pub state: Option<StateType>, + pub title: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub user: Option<User>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueConfig { + pub blank_issues_enabled: Option<bool>, + pub contact_links: Option<Vec<IssueConfigContactLink>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueConfigContactLink { + pub about: Option<String>, + pub name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueConfigValidation { + pub message: Option<String>, + pub valid: Option<bool>, +} + +/// IssueDeadline represents an issue deadline +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueDeadline { + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, +} + +/// IssueFormField represents a form field +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueFormField { + pub attributes: Option<BTreeMap<String, serde_json::Value>>, + pub id: Option<String>, + #[serde(rename = "type")] + pub r#type: Option<String>, + pub validations: Option<BTreeMap<String, serde_json::Value>>, + pub visible: Option<Vec<String>>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueFormFieldType {} + +/// IssueFormFieldVisible defines issue form field visible +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueFormFieldVisible {} + +/// IssueLabelsOption a collection of labels +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueLabelsOption { + /// Labels can be a list of integers representing label IDs + /// + /// or a list of strings representing label names + pub labels: Option<Vec<serde_json::Value>>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// IssueMeta basic issue information +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueMeta { + pub index: Option<i64>, + pub owner: Option<String>, + pub repo: Option<String>, +} + +/// IssueTemplate represents an issue template for a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct IssueTemplate { + pub about: Option<String>, + pub body: Option<Vec<IssueFormField>>, + pub content: Option<String>, + pub file_name: Option<String>, + pub labels: Option<Vec<String>>, + pub name: Option<String>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + pub title: Option<String>, +} + +/// Label a label to an issue or a pr +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Label { + pub color: Option<String>, + pub description: Option<String>, + pub exclusive: Option<bool>, + pub id: Option<i64>, + pub is_archived: Option<bool>, + pub name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// LabelTemplate info of a Label template +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct LabelTemplate { + pub color: Option<String>, + pub description: Option<String>, + pub exclusive: Option<bool>, + pub name: Option<String>, +} + +/// LicensesInfo contains information about a License +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct LicenseTemplateInfo { + pub body: Option<String>, + pub implementation: Option<String>, + pub key: Option<String>, + pub name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// LicensesListEntry is used for the API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct LicensesTemplateListEntry { + pub key: Option<String>, + pub name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// MarkdownOption markdown options +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct MarkdownOption { + /// Context to render + /// + /// + /// + /// in: body + #[serde(rename = "Context")] + pub context: Option<String>, + /// Mode to render (comment, gfm, markdown) + /// + /// + /// + /// in: body + #[serde(rename = "Mode")] + pub mode: Option<String>, + /// Text markdown to render + /// + /// + /// + /// in: body + #[serde(rename = "Text")] + pub text: Option<String>, + /// Is it a wiki page ? + /// + /// + /// + /// in: body + #[serde(rename = "Wiki")] + pub wiki: Option<bool>, +} + +/// MarkupOption markup options +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct MarkupOption { + /// Context to render + /// + /// + /// + /// in: body + #[serde(rename = "Context")] + pub context: Option<String>, + /// File path for detecting extension in file mode + /// + /// + /// + /// in: body + #[serde(rename = "FilePath")] + pub file_path: Option<String>, + /// Mode to render (comment, gfm, markdown, file) + /// + /// + /// + /// in: body + #[serde(rename = "Mode")] + pub mode: Option<String>, + /// Text markup to render + /// + /// + /// + /// in: body + #[serde(rename = "Text")] + pub text: Option<String>, + /// Is it a wiki page ? + /// + /// + /// + /// in: body + #[serde(rename = "Wiki")] + pub wiki: Option<bool>, +} + +/// MergePullRequestForm form for merging Pull Request +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct MergePullRequestOption { + #[serde(rename = "Do")] + pub r#do: MergePullRequestOptionDo, + #[serde(rename = "MergeCommitID")] + pub merge_commit_id: Option<String>, + #[serde(rename = "MergeMessageField")] + pub merge_message_field: Option<String>, + #[serde(rename = "MergeTitleField")] + pub merge_title_field: Option<String>, + pub delete_branch_after_merge: Option<bool>, + pub force_merge: Option<bool>, + pub head_commit_id: Option<String>, + pub merge_when_checks_succeed: Option<bool>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum MergePullRequestOptionDo { + #[serde(rename = "merge")] + Merge, + #[serde(rename = "rebase")] + Rebase, + #[serde(rename = "rebase-merge")] + RebaseMerge, + #[serde(rename = "squash")] + Squash, + #[serde(rename = "fast-forward-only")] + FastForwardOnly, + #[serde(rename = "manually-merged")] + ManuallyMerged, +} +/// MigrateRepoOptions options for migrating repository's +/// +/// this is used to interact with api v1 +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct MigrateRepoOptions { + pub auth_password: Option<String>, + pub auth_token: Option<String>, + pub auth_username: Option<String>, + pub clone_addr: String, + pub description: Option<String>, + pub issues: Option<bool>, + pub labels: Option<bool>, + pub lfs: Option<bool>, + pub lfs_endpoint: Option<String>, + pub milestones: Option<bool>, + pub mirror: Option<bool>, + pub mirror_interval: Option<String>, + pub private: Option<bool>, + pub pull_requests: Option<bool>, + pub releases: Option<bool>, + pub repo_name: String, + /// Name of User or Organisation who will own Repo after migration + pub repo_owner: Option<String>, + pub service: Option<MigrateRepoOptionsService>, + /// deprecated (only for backwards compatibility) + pub uid: Option<i64>, + pub wiki: Option<bool>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum MigrateRepoOptionsService { + #[serde(rename = "git")] + Git, + #[serde(rename = "github")] + Github, + #[serde(rename = "gitea")] + Gitea, + #[serde(rename = "gitlab")] + Gitlab, + #[serde(rename = "gogs")] + Gogs, + #[serde(rename = "onedev")] + Onedev, + #[serde(rename = "gitbucket")] + Gitbucket, + #[serde(rename = "codebase")] + Codebase, +} +/// Milestone milestone is a collection of issues on one repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Milestone { + #[serde(with = "time::serde::rfc3339::option")] + pub closed_at: Option<time::OffsetDateTime>, + pub closed_issues: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub description: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_on: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub open_issues: Option<i64>, + pub state: Option<StateType>, + pub title: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, +} + +/// NewIssuePinsAllowed represents an API response that says if new Issue Pins are allowed +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NewIssuePinsAllowed { + pub issues: Option<bool>, + pub pull_requests: Option<bool>, +} + +/// NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NodeInfo { + pub metadata: Option<BTreeMap<String, serde_json::Value>>, + #[serde(rename = "openRegistrations")] + pub open_registrations: Option<bool>, + pub protocols: Option<Vec<String>>, + pub services: Option<NodeInfoServices>, + pub software: Option<NodeInfoSoftware>, + pub usage: Option<NodeInfoUsage>, + pub version: Option<String>, +} + +/// NodeInfoServices contains the third party sites this server can connect to via their application API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NodeInfoServices { + pub inbound: Option<Vec<String>>, + pub outbound: Option<Vec<String>>, +} + +/// NodeInfoSoftware contains Metadata about server software in use +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NodeInfoSoftware { + pub homepage: Option<String>, + pub name: Option<String>, + pub repository: Option<String>, + pub version: Option<String>, +} + +/// NodeInfoUsage contains usage statistics for this server +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NodeInfoUsage { + #[serde(rename = "localComments")] + pub local_comments: Option<i64>, + #[serde(rename = "localPosts")] + pub local_posts: Option<i64>, + pub users: Option<NodeInfoUsageUsers>, +} + +/// NodeInfoUsageUsers contains statistics about the users of this server +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NodeInfoUsageUsers { + #[serde(rename = "activeHalfyear")] + pub active_halfyear: Option<i64>, + #[serde(rename = "activeMonth")] + pub active_month: Option<i64>, + pub total: Option<i64>, +} + +/// Note contains information related to a git note +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Note { + pub commit: Option<Commit>, + pub message: Option<String>, +} + +/// NotificationCount number of unread notifications +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NotificationCount { + pub new: Option<i64>, +} + +/// NotificationSubject contains the notification subject (Issue/Pull/Commit) +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NotificationSubject { + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub latest_comment_html_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub latest_comment_url: Option<url::Url>, + pub state: Option<StateType>, + pub title: Option<String>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// NotificationThread expose Notification on API +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NotificationThread { + pub id: Option<i64>, + pub pinned: Option<bool>, + pub repository: Option<Repository>, + pub subject: Option<NotificationSubject>, + pub unread: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// NotifySubjectType represent type of notification subject +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct NotifySubjectType {} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct OAuth2Application { + pub client_id: Option<String>, + pub client_secret: Option<String>, + pub confidential_client: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub name: Option<String>, + pub redirect_uris: Option<Vec<String>>, +} + +/// ObjectFormatName of the underlying git repository + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum ObjectFormatName { + #[serde(rename = "sha1")] + Sha1, + #[serde(rename = "sha256")] + Sha256, +} +/// Organization represents an organization +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Organization { + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub avatar_url: Option<url::Url>, + pub description: Option<String>, + pub email: Option<String>, + pub full_name: Option<String>, + pub id: Option<i64>, + pub location: Option<String>, + pub name: Option<String>, + pub repo_admin_change_team_access: Option<bool>, + /// deprecated + pub username: Option<String>, + pub visibility: Option<String>, + pub website: Option<String>, +} + +/// OrganizationPermissions list different users permissions on an organization +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct OrganizationPermissions { + pub can_create_repository: Option<bool>, + pub can_read: Option<bool>, + pub can_write: Option<bool>, + pub is_admin: Option<bool>, + pub is_owner: Option<bool>, +} + +/// PRBranchInfo information about a branch +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PRBranchInfo { + pub label: Option<String>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + pub repo: Option<Repository>, + pub repo_id: Option<i64>, + pub sha: Option<String>, +} + +/// Package represents a package +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Package { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub creator: Option<User>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub name: Option<String>, + pub owner: Option<User>, + pub repository: Option<Repository>, + #[serde(rename = "type")] + pub r#type: Option<String>, + pub version: Option<String>, +} + +/// PackageFile represents a package file +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PackageFile { + #[serde(rename = "Size")] + pub size: Option<i64>, + pub id: Option<i64>, + pub md5: Option<String>, + pub name: Option<String>, + pub sha1: Option<String>, + pub sha256: Option<String>, + pub sha512: Option<String>, +} + +/// PayloadCommit represents a commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PayloadCommit { + pub added: Option<Vec<String>>, + pub author: Option<PayloadUser>, + pub committer: Option<PayloadUser>, + /// sha1 hash of the commit + pub id: Option<String>, + pub message: Option<String>, + pub modified: Option<Vec<String>>, + pub removed: Option<Vec<String>>, + #[serde(with = "time::serde::rfc3339::option")] + pub timestamp: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub verification: Option<PayloadCommitVerification>, +} + +/// PayloadCommitVerification represents the GPG verification of a commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PayloadCommitVerification { + pub payload: Option<String>, + pub reason: Option<String>, + pub signature: Option<String>, + pub signer: Option<PayloadUser>, + pub verified: Option<bool>, +} + +/// PayloadUser represents the author or committer of a commit +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PayloadUser { + pub email: Option<String>, + /// Full name of the commit author + pub name: Option<String>, + pub username: Option<String>, +} + +/// Permission represents a set of permissions +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Permission { + pub admin: Option<bool>, + pub pull: Option<bool>, + pub push: Option<bool>, +} + +/// PublicKey publickey is a user key to push code to repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PublicKey { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub fingerprint: Option<String>, + pub id: Option<i64>, + pub key: Option<String>, + pub key_type: Option<String>, + pub read_only: Option<bool>, + pub title: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub user: Option<User>, +} + +/// PullRequest represents a pull request +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PullRequest { + pub additions: Option<i64>, + pub allow_maintainer_edit: Option<bool>, + pub assignee: Option<User>, + pub assignees: Option<Vec<User>>, + pub base: Option<PRBranchInfo>, + pub body: Option<String>, + pub changed_files: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub closed_at: Option<time::OffsetDateTime>, + pub comments: Option<i64>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub deletions: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub diff_url: Option<url::Url>, + pub draft: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub due_date: Option<time::OffsetDateTime>, + pub head: Option<PRBranchInfo>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub is_locked: Option<bool>, + pub labels: Option<Vec<Label>>, + pub merge_base: Option<String>, + pub merge_commit_sha: Option<String>, + pub mergeable: Option<bool>, + pub merged: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub merged_at: Option<time::OffsetDateTime>, + pub merged_by: Option<User>, + pub milestone: Option<Milestone>, + pub number: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub patch_url: Option<url::Url>, + pub pin_order: Option<i64>, + #[serde(deserialize_with = "crate::requested_reviewers_ignore_null")] + pub requested_reviewers: Option<Vec<User>>, + /// number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR) + pub review_comments: Option<i64>, + pub state: Option<StateType>, + pub title: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub user: Option<User>, +} + +/// PullRequestMeta PR info if an issue is a PR +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PullRequestMeta { + pub draft: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub merged: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub merged_at: Option<time::OffsetDateTime>, +} + +/// PullReview represents a pull request review +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PullReview { + pub body: Option<String>, + pub comments_count: Option<i64>, + pub commit_id: Option<String>, + pub dismissed: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub official: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub pull_request_url: Option<url::Url>, + pub stale: Option<bool>, + pub state: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub submitted_at: Option<time::OffsetDateTime>, + pub team: Option<Team>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + pub user: Option<User>, +} + +/// PullReviewComment represents a comment on a pull request review +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PullReviewComment { + pub body: Option<String>, + pub commit_id: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub diff_hunk: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub original_commit_id: Option<String>, + pub original_position: Option<u64>, + pub path: Option<String>, + pub position: Option<u64>, + pub pull_request_review_id: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub pull_request_url: Option<url::Url>, + pub resolver: Option<User>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + pub user: Option<User>, +} + +/// PullReviewRequestOptions are options to add or remove pull review requests +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PullReviewRequestOptions { + pub reviewers: Option<Vec<String>>, + pub team_reviewers: Option<Vec<String>>, +} + +/// PushMirror represents information of a push mirror +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct PushMirror { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub interval: Option<String>, + pub last_error: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub last_update: Option<time::OffsetDateTime>, + pub remote_address: Option<String>, + pub remote_name: Option<String>, + pub repo_name: Option<String>, + pub sync_on_commit: Option<bool>, +} + +/// Reaction contain one reaction +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Reaction { + pub content: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub user: Option<User>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Reference { + pub object: Option<GitObject>, + #[serde(rename = "ref")] + pub r#ref: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// Release represents a repository release +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Release { + pub archive_download_count: Option<TagArchiveDownloadCount>, + pub assets: Option<Vec<Attachment>>, + pub author: Option<User>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub draft: Option<bool>, + pub hide_archive_links: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub name: Option<String>, + pub prerelease: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub published_at: Option<time::OffsetDateTime>, + pub tag_name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub tarball_url: Option<url::Url>, + pub target_commitish: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub upload_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub zipball_url: Option<url::Url>, +} + +/// RenameUserOption options when renaming a user +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RenameUserOption { + /// New username for this user. This name cannot be in use yet by any other user. + pub new_username: String, +} + +/// ReplaceFlagsOption options when replacing the flags of a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ReplaceFlagsOption { + pub flags: Option<Vec<String>>, +} + +/// RepoCollaboratorPermission to get repository permission for a collaborator +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RepoCollaboratorPermission { + pub permission: Option<String>, + pub role_name: Option<String>, + pub user: Option<User>, +} + +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RepoCommit { + pub author: Option<CommitUser>, + pub committer: Option<CommitUser>, + pub message: Option<String>, + pub tree: Option<CommitMeta>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub verification: Option<PayloadCommitVerification>, +} + +/// RepoTopicOptions a collection of repo topic names +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RepoTopicOptions { + /// list of topic names + pub topics: Option<Vec<String>>, +} + +/// RepoTransfer represents a pending repo transfer +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RepoTransfer { + pub doer: Option<User>, + pub recipient: Option<User>, + pub teams: Option<Vec<Team>>, +} + +/// Repository represents a repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Repository { + pub allow_fast_forward_only_merge: Option<bool>, + pub allow_merge_commits: Option<bool>, + pub allow_rebase: Option<bool>, + pub allow_rebase_explicit: Option<bool>, + pub allow_rebase_update: Option<bool>, + pub allow_squash_merge: Option<bool>, + pub archived: Option<bool>, + #[serde(with = "time::serde::rfc3339::option")] + pub archived_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub avatar_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub clone_url: Option<url::Url>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub default_allow_maintainer_edit: Option<bool>, + pub default_branch: Option<String>, + pub default_delete_branch_after_merge: Option<bool>, + pub default_merge_style: Option<DefaultMergeStyle>, + pub description: Option<String>, + pub empty: Option<bool>, + pub external_tracker: Option<ExternalTracker>, + pub external_wiki: Option<ExternalWiki>, + pub fork: Option<bool>, + pub forks_count: Option<i64>, + pub full_name: Option<String>, + pub globally_editable_wiki: Option<bool>, + pub has_actions: Option<bool>, + pub has_issues: Option<bool>, + pub has_packages: Option<bool>, + pub has_projects: Option<bool>, + pub has_pull_requests: Option<bool>, + pub has_releases: Option<bool>, + pub has_wiki: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + pub ignore_whitespace_conflicts: Option<bool>, + pub internal: Option<bool>, + pub internal_tracker: Option<InternalTracker>, + pub language: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub languages_url: Option<url::Url>, + pub link: Option<String>, + pub mirror: Option<bool>, + pub mirror_interval: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub mirror_updated: Option<time::OffsetDateTime>, + pub name: Option<String>, + pub object_format_name: Option<ObjectFormatName>, + pub open_issues_count: Option<i64>, + pub open_pr_counter: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub original_url: Option<url::Url>, + pub owner: Option<User>, + pub parent: Option<Box<Repository>>, + pub permissions: Option<Permission>, + pub private: Option<bool>, + pub release_counter: Option<i64>, + pub repo_transfer: Option<RepoTransfer>, + pub size: Option<i64>, + #[serde(deserialize_with = "crate::deserialize_optional_ssh_url")] + pub ssh_url: Option<url::Url>, + pub stars_count: Option<i64>, + pub template: Option<bool>, + pub topics: Option<Vec<String>>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, + pub watchers_count: Option<i64>, + pub website: Option<String>, + pub wiki_branch: Option<String>, +} + +/// RepositoryMeta basic repository information +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct RepositoryMeta { + pub full_name: Option<String>, + pub id: Option<i64>, + pub name: Option<String>, + pub owner: Option<String>, +} + +/// ReviewStateType review state type +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ReviewStateType {} + +/// SearchResults results of a successful search +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct SearchResults { + pub data: Option<Vec<Repository>>, + pub ok: Option<bool>, +} + +/// Secret represents a secret +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Secret { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + /// the secret's name + pub name: Option<String>, +} + +/// ServerVersion wraps the version of the server +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct ServerVersion { + pub version: Option<String>, +} + +/// StateType issue state type + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum StateType { + #[serde(rename = "open")] + Open, + #[serde(rename = "closed")] + Closed, +} +/// StopWatch represent a running stopwatch +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct StopWatch { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub duration: Option<String>, + pub issue_index: Option<i64>, + pub issue_title: Option<String>, + pub repo_name: Option<String>, + pub repo_owner_name: Option<String>, + pub seconds: Option<i64>, +} + +/// SubmitPullReviewOptions are options to submit a pending pull review +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct SubmitPullReviewOptions { + pub body: Option<String>, + pub event: Option<String>, +} + +/// Tag represents a repository tag +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Tag { + pub archive_download_count: Option<TagArchiveDownloadCount>, + pub commit: Option<CommitMeta>, + pub id: Option<String>, + pub message: Option<String>, + pub name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub tarball_url: Option<url::Url>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub zipball_url: Option<url::Url>, +} + +/// TagArchiveDownloadCount counts how many times a archive was downloaded +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TagArchiveDownloadCount { + pub tar_gz: Option<i64>, + pub zip: Option<i64>, +} + +/// TagProtection represents a tag protection +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TagProtection { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub name_pattern: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + pub whitelist_teams: Option<Vec<String>>, + pub whitelist_usernames: Option<Vec<String>>, +} + +/// Team represents a team in an organization +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct Team { + pub can_create_org_repo: Option<bool>, + pub description: Option<String>, + pub id: Option<i64>, + pub includes_all_repositories: Option<bool>, + pub name: Option<String>, + pub organization: Option<Organization>, + pub permission: Option<TeamPermission>, + pub units: Option<Vec<String>>, + pub units_map: Option<BTreeMap<String, String>>, +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum TeamPermission { + #[serde(rename = "none")] + None, + #[serde(rename = "read")] + Read, + #[serde(rename = "write")] + Write, + #[serde(rename = "admin")] + Admin, + #[serde(rename = "owner")] + Owner, +} +/// TimeStamp defines a timestamp +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TimeStamp {} + +/// TimelineComment represents a timeline comment (comment of any type) on a commit or issue +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TimelineComment { + pub assignee: Option<User>, + pub assignee_team: Option<Team>, + pub body: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub dependent_issue: Option<Issue>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub id: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub issue_url: Option<url::Url>, + pub label: Option<Label>, + pub milestone: Option<Milestone>, + pub new_ref: Option<String>, + pub new_title: Option<String>, + pub old_milestone: Option<Milestone>, + pub old_project_id: Option<i64>, + pub old_ref: Option<String>, + pub old_title: Option<String>, + pub project_id: Option<i64>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub pull_request_url: Option<url::Url>, + pub ref_action: Option<String>, + pub ref_comment: Option<Comment>, + /// commit SHA where issue/PR was referenced + pub ref_commit_sha: Option<String>, + pub ref_issue: Option<Issue>, + /// whether the assignees were removed or added + pub removed_assignee: Option<bool>, + pub resolve_doer: Option<User>, + pub review_id: Option<i64>, + pub tracked_time: Option<TrackedTime>, + #[serde(rename = "type")] + pub r#type: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated_at: Option<time::OffsetDateTime>, + pub user: Option<User>, +} + +/// TopicName a list of repo topic names +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TopicName { + pub topics: Option<Vec<String>>, +} + +/// TopicResponse for returning topics +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TopicResponse { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub repo_count: Option<i64>, + pub topic_name: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub updated: Option<time::OffsetDateTime>, +} + +/// TrackedTime worked time for an issue / pr +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TrackedTime { + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + pub id: Option<i64>, + pub issue: Option<Issue>, + /// deprecated (only for backwards compatibility) + pub issue_id: Option<i64>, + /// Time in seconds + pub time: Option<i64>, + /// deprecated (only for backwards compatibility) + pub user_id: Option<i64>, + pub user_name: Option<String>, +} + +/// TransferRepoOption options when transfer a repository's ownership +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TransferRepoOption { + pub new_owner: String, + /// ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories. + pub team_ids: Option<Vec<i64>>, +} + +/// 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) +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UpdateFileOptions { + pub author: Option<Identity>, + /// branch (optional) to base this file from. if not given, the default branch is used + pub branch: Option<String>, + pub committer: Option<Identity>, + /// content must be base64 encoded + pub content: String, + pub dates: Option<CommitDateOptions>, + /// from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL + pub from_path: Option<String>, + /// message (optional) for the commit of this file. if not supplied, a default message will be used + pub message: Option<String>, + /// new_branch (optional) will make a new branch from `branch` before creating the file + pub new_branch: Option<String>, + /// sha is the SHA for the file that already exists + pub sha: String, + /// Add a Signed-off-by trailer by the committer at the end of the commit log message. + pub signoff: Option<bool>, +} + +/// UpdateRepoAvatarUserOption options when updating the repo avatar +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UpdateRepoAvatarOption { + /// image must be base64 encoded + pub image: Option<String>, +} + +/// UpdateUserAvatarUserOption options when updating the user avatar +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UpdateUserAvatarOption { + /// image must be base64 encoded + pub image: Option<String>, +} + +/// UpdateVariableOption the option when updating variable +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UpdateVariableOption { + /// New name for the variable. If the field is empty, the variable name won't be updated. + pub name: Option<String>, + /// Value of the variable to update + pub value: String, +} + +/// User represents a user +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct User { + /// Is user active + pub active: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + /// URL to the user's avatar + pub avatar_url: Option<url::Url>, + #[serde(with = "time::serde::rfc3339::option")] + pub created: Option<time::OffsetDateTime>, + /// the user's description + pub description: Option<String>, + pub email: Option<String>, + /// user counts + pub followers_count: Option<i64>, + pub following_count: Option<i64>, + /// the user's full name + pub full_name: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + /// URL to the user's Forgejo page + pub html_url: Option<url::Url>, + /// the user's id + pub id: Option<i64>, + /// Is the user an administrator + pub is_admin: Option<bool>, + /// User locale + pub language: Option<String>, + #[serde(with = "time::serde::rfc3339::option")] + pub last_login: Option<time::OffsetDateTime>, + /// the user's location + pub location: Option<String>, + /// the user's username + pub login: Option<String>, + /// the user's authentication sign-in name. + pub login_name: Option<String>, + /// Is user login prohibited + pub prohibit_login: Option<bool>, + /// the user's pronouns + pub pronouns: Option<String>, + /// Is user restricted + pub restricted: Option<bool>, + /// The ID of the user's Authentication Source + pub source_id: Option<i64>, + pub starred_repos_count: Option<i64>, + /// User visibility level option: public, limited, private + pub visibility: Option<String>, + /// the user's website + pub website: Option<String>, +} + +/// UserHeatmapData represents the data needed to create a heatmap +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UserHeatmapData { + pub contributions: Option<i64>, + pub timestamp: Option<i64>, +} + +/// UserSettings represents user settings +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UserSettings { + pub description: Option<String>, + pub diff_view_style: Option<String>, + pub enable_repo_unit_hints: Option<bool>, + pub full_name: Option<String>, + pub hide_activity: Option<bool>, + /// Privacy + pub hide_email: Option<bool>, + pub language: Option<String>, + pub location: Option<String>, + pub pronouns: Option<String>, + pub theme: Option<String>, + pub website: Option<String>, +} + +/// UserSettingsOptions represents options to change user settings +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UserSettingsOptions { + pub description: Option<String>, + pub diff_view_style: Option<String>, + pub enable_repo_unit_hints: Option<bool>, + pub full_name: Option<String>, + pub hide_activity: Option<bool>, + /// Privacy + pub hide_email: Option<bool>, + pub language: Option<String>, + pub location: Option<String>, + pub pronouns: Option<String>, + pub theme: Option<String>, + pub website: Option<String>, +} + +/// WatchInfo represents an API watch status of one repository +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct WatchInfo { + #[serde(with = "time::serde::rfc3339::option")] + pub created_at: Option<time::OffsetDateTime>, + pub ignored: Option<bool>, + pub reason: Option<serde_json::Value>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub repository_url: Option<url::Url>, + pub subscribed: Option<bool>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub url: Option<url::Url>, +} + +/// WikiCommit page commit/revision +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct WikiCommit { + pub author: Option<CommitUser>, + pub commiter: Option<CommitUser>, + pub message: Option<String>, + pub sha: Option<String>, +} + +/// WikiCommitList commit/revision list +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct WikiCommitList { + pub commits: Option<Vec<WikiCommit>>, + pub count: Option<i64>, +} + +/// WikiPage a wiki page +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct WikiPage { + pub commit_count: Option<i64>, + /// Page content, base64 encoded + pub content_base64: Option<String>, + pub footer: Option<String>, + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub last_commit: Option<WikiCommit>, + pub sidebar: Option<String>, + pub sub_url: Option<String>, + pub title: Option<String>, +} + +/// WikiPageMetaData wiki page meta information +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct WikiPageMetaData { + #[serde(deserialize_with = "crate::none_if_blank_url")] + pub html_url: Option<url::Url>, + pub last_commit: Option<WikiCommit>, + pub sub_url: Option<String>, + pub title: Option<String>, +} + +pub struct ChangedFileListHeaders { + pub x_has_more: Option<bool>, + pub x_page: Option<i64>, + pub x_page_count: Option<i64>, + pub x_per_page: Option<i64>, + pub x_total_count: Option<i64>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for ChangedFileListHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let x_has_more = map + .get("X-HasMore") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<bool>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_page = map + .get("X-Page") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_page_count = map + .get("X-PageCount") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_per_page = map + .get("X-PerPage") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_total_count = map + .get("X-Total-Count") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { + x_has_more, + x_page, + x_page_count, + x_per_page, + x_total_count, + }) + } +} + +pub struct CommitListHeaders { + pub x_has_more: Option<bool>, + pub x_page: Option<i64>, + pub x_page_count: Option<i64>, + pub x_per_page: Option<i64>, + pub x_total: Option<i64>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for CommitListHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let x_has_more = map + .get("X-HasMore") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<bool>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_page = map + .get("X-Page") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_page_count = map + .get("X-PageCount") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_per_page = map + .get("X-PerPage") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + let x_total = map + .get("X-Total") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<i64>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { + x_has_more, + x_page, + x_page_count, + x_per_page, + x_total, + }) + } +} + +pub struct RegistrationTokenHeaders { + pub token: Option<String>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for RegistrationTokenHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let token = map + .get("token") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + Ok(Self { token }) + } +} + +pub struct ErrorHeaders { + pub message: Option<String>, + pub url: Option<url::Url>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for ErrorHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let message = map + .get("message") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + let url = map + .get("url") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<url::Url>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { message, url }) + } +} + +pub struct ForbiddenHeaders { + pub message: Option<String>, + pub url: Option<url::Url>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for ForbiddenHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let message = map + .get("message") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + let url = map + .get("url") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<url::Url>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { message, url }) + } +} + +pub struct InvalidTopicsErrorHeaders { + pub invalid_topics: Option<Vec<String>>, + pub message: Option<String>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for InvalidTopicsErrorHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let invalid_topics = map + .get("invalidTopics") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.split(",").map(|s| s.to_string()).collect::<Vec<_>>()) + }) + .transpose()?; + let message = map + .get("message") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + Ok(Self { + invalid_topics, + message, + }) + } +} + +pub struct RepoArchivedErrorHeaders { + pub message: Option<String>, + pub url: Option<url::Url>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for RepoArchivedErrorHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let message = map + .get("message") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + let url = map + .get("url") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<url::Url>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { message, url }) + } +} + +pub struct ValidationErrorHeaders { + pub message: Option<String>, + pub url: Option<url::Url>, +} + +impl TryFrom<&reqwest::header::HeaderMap> for ValidationErrorHeaders { + type Error = StructureError; + + fn try_from(map: &reqwest::header::HeaderMap) -> Result<Self, Self::Error> { + let message = map + .get("message") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + Ok(s.to_string()) + }) + .transpose()?; + let url = map + .get("url") + .map(|s| -> Result<_, _> { + let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?; + s.parse::<url::Url>() + .map_err(|_| StructureError::HeaderParseFailed) + }) + .transpose()?; + Ok(Self { message, url }) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminCronListQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminCronListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminGetAllEmailsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminGetAllEmailsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminSearchEmailsQuery { + /// keyword + pub q: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminSearchEmailsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminListHooksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminListHooksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminGetAllOrgsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminGetAllOrgsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminUnadoptedListQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, + /// pattern of repositories to search for + pub pattern: Option<String>, +} + +impl std::fmt::Display for AdminUnadoptedListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(pattern) = &self.pattern { + write!(f, "pattern={pattern}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminSearchUsersQuery { + /// ID of the user's login source to search for + pub source_id: Option<u64>, + /// user's login name to search for + pub login_name: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for AdminSearchUsersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(source_id) = &self.source_id { + write!(f, "source_id={source_id}&")?; + } + if let Some(login_name) = &self.login_name { + write!(f, "login_name={login_name}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct AdminDeleteUserQuery { + /// purge the user from the system completely + pub purge: Option<bool>, +} + +impl std::fmt::Display for AdminDeleteUserQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(purge) = &self.purge { + write!(f, "purge={purge}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct NotifyGetListQuery { + /// If true, show notifications marked as read. Default value is false + pub all: Option<bool>, + /// Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned. + pub status_types: Option<Vec<String>>, + /// filter notifications by subject type + pub subject_type: Option<Vec<NotifyGetListQuerySubjectType>>, + /// Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for NotifyGetListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(all) = &self.all { + write!(f, "all={all}&")?; + } + if let Some(status_types) = &self.status_types { + if !status_types.is_empty() { + for item in status_types { + write!(f, "status-types=")?; + write!(f, "{item}")?; + write!(f, "&")?; + } + } + } + if let Some(subject_type) = &self.subject_type { + if !subject_type.is_empty() { + for item in subject_type { + write!(f, "subject-type=")?; + write!(f, "{}", item.as_str())?; + write!(f, "&")?; + } + } + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum NotifyGetListQuerySubjectType { + #[serde(rename = "issue")] + Issue, + #[serde(rename = "pull")] + Pull, + #[serde(rename = "commit")] + Commit, + #[serde(rename = "repository")] + Repository, +} + +impl NotifyGetListQuerySubjectType { + fn as_str(&self) -> &'static str { + match self { + NotifyGetListQuerySubjectType::Issue => "issue", + NotifyGetListQuerySubjectType::Pull => "pull", + NotifyGetListQuerySubjectType::Commit => "commit", + NotifyGetListQuerySubjectType::Repository => "repository", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct NotifyReadListQuery { + /// Describes the last point that notifications were checked. Anything updated since this time will not be updated. + pub last_read_at: Option<time::OffsetDateTime>, + /// If true, mark all notifications on this repo. Default value is false + pub all: Option<String>, + /// Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread. + pub status_types: Option<Vec<String>>, + /// Status to mark notifications as, Defaults to read. + pub to_status: Option<String>, +} + +impl std::fmt::Display for NotifyReadListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(last_read_at) = &self.last_read_at { + write!( + f, + "last_read_at={field_name}&", + field_name = last_read_at + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(all) = &self.all { + write!(f, "all={all}&")?; + } + if let Some(status_types) = &self.status_types { + if !status_types.is_empty() { + for item in status_types { + write!(f, "status-types=")?; + write!(f, "{item}")?; + write!(f, "&")?; + } + } + } + if let Some(to_status) = &self.to_status { + write!(f, "to-status={to_status}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct NotifyReadThreadQuery { + /// Status to mark notifications as + pub to_status: Option<String>, +} + +impl std::fmt::Display for NotifyReadThreadQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(to_status) = &self.to_status { + write!(f, "to-status={to_status}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgGetAllQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgGetAllQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListActionsSecretsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListActionsSecretsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct GetOrgVariablesListQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for GetOrgVariablesListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListActivityFeedsQuery { + /// the date of the activities to be found + pub date: Option<time::Date>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListActivityFeedsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(date) = &self.date { + write!( + f, + "date={field_name}&", + field_name = date + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListHooksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListHooksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListLabelsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListLabelsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListBlockedUsersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListBlockedUsersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListMembersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListMembersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListPublicMembersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListPublicMembersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListReposQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListReposQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListTeamsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListTeamsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct TeamSearchQuery { + /// keywords to search + pub q: Option<String>, + /// include search within team description (defaults to true) + pub include_desc: Option<bool>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for TeamSearchQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(include_desc) = &self.include_desc { + write!(f, "include_desc={include_desc}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct TeamSearchResponse { + pub data: Option<Vec<Team>>, + pub ok: Option<bool>, +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct ListPackagesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, + /// package type filter + pub r#type: Option<ListPackagesQueryType>, + /// name filter + pub q: Option<String>, +} + +impl std::fmt::Display for ListPackagesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(r#type) = &self.r#type { + write!(f, "type={}&", r#type.as_str())?; + } + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum ListPackagesQueryType { + #[serde(rename = "alpine")] + Alpine, + #[serde(rename = "cargo")] + Cargo, + #[serde(rename = "chef")] + Chef, + #[serde(rename = "composer")] + Composer, + #[serde(rename = "conan")] + Conan, + #[serde(rename = "conda")] + Conda, + #[serde(rename = "container")] + Container, + #[serde(rename = "cran")] + Cran, + #[serde(rename = "debian")] + Debian, + #[serde(rename = "generic")] + Generic, + #[serde(rename = "go")] + Go, + #[serde(rename = "helm")] + Helm, + #[serde(rename = "maven")] + Maven, + #[serde(rename = "npm")] + Npm, + #[serde(rename = "nuget")] + Nuget, + #[serde(rename = "pub")] + Pub, + #[serde(rename = "pypi")] + Pypi, + #[serde(rename = "rpm")] + Rpm, + #[serde(rename = "rubygems")] + Rubygems, + #[serde(rename = "swift")] + Swift, + #[serde(rename = "vagrant")] + Vagrant, +} + +impl ListPackagesQueryType { + fn as_str(&self) -> &'static str { + match self { + ListPackagesQueryType::Alpine => "alpine", + ListPackagesQueryType::Cargo => "cargo", + ListPackagesQueryType::Chef => "chef", + ListPackagesQueryType::Composer => "composer", + ListPackagesQueryType::Conan => "conan", + ListPackagesQueryType::Conda => "conda", + ListPackagesQueryType::Container => "container", + ListPackagesQueryType::Cran => "cran", + ListPackagesQueryType::Debian => "debian", + ListPackagesQueryType::Generic => "generic", + ListPackagesQueryType::Go => "go", + ListPackagesQueryType::Helm => "helm", + ListPackagesQueryType::Maven => "maven", + ListPackagesQueryType::Npm => "npm", + ListPackagesQueryType::Nuget => "nuget", + ListPackagesQueryType::Pub => "pub", + ListPackagesQueryType::Pypi => "pypi", + ListPackagesQueryType::Rpm => "rpm", + ListPackagesQueryType::Rubygems => "rubygems", + ListPackagesQueryType::Swift => "swift", + ListPackagesQueryType::Vagrant => "vagrant", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueSearchIssuesQuery { + /// whether issue is open or closed + pub state: Option<String>, + /// comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded + pub labels: Option<String>, + /// comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded + pub milestones: Option<String>, + /// search string + pub q: Option<String>, + /// repository to prioritize in the results + pub priority_repo_id: Option<u64>, + /// filter by type (issues / pulls) if set + pub r#type: Option<String>, + /// Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// filter (issues / pulls) assigned to you, default is false + pub assigned: Option<bool>, + /// filter (issues / pulls) created by you, default is false + pub created: Option<bool>, + /// filter (issues / pulls) mentioning you, default is false + pub mentioned: Option<bool>, + /// filter pulls requesting your review, default is false + pub review_requested: Option<bool>, + /// filter pulls reviewed by you, default is false + pub reviewed: Option<bool>, + /// filter by owner + pub owner: Option<String>, + /// filter by team (requires organization owner parameter to be provided) + pub team: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueSearchIssuesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(state) = &self.state { + write!(f, "state={state}&")?; + } + if let Some(labels) = &self.labels { + write!(f, "labels={labels}&")?; + } + if let Some(milestones) = &self.milestones { + write!(f, "milestones={milestones}&")?; + } + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(priority_repo_id) = &self.priority_repo_id { + write!(f, "priority_repo_id={priority_repo_id}&")?; + } + if let Some(r#type) = &self.r#type { + write!(f, "type={type}&")?; + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(assigned) = &self.assigned { + write!(f, "assigned={assigned}&")?; + } + if let Some(created) = &self.created { + write!(f, "created={created}&")?; + } + if let Some(mentioned) = &self.mentioned { + write!(f, "mentioned={mentioned}&")?; + } + if let Some(review_requested) = &self.review_requested { + write!(f, "review_requested={review_requested}&")?; + } + if let Some(reviewed) = &self.reviewed { + write!(f, "reviewed={reviewed}&")?; + } + if let Some(owner) = &self.owner { + write!(f, "owner={owner}&")?; + } + if let Some(team) = &self.team { + write!(f, "team={team}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoSearchQuery { + /// keyword + pub q: Option<String>, + /// Limit search to repositories with keyword as topic + pub topic: Option<bool>, + /// include search of keyword within repository description + pub include_desc: Option<bool>, + /// search only for repos that the user with the given id owns or contributes to + pub uid: Option<u64>, + /// repo owner to prioritize in the results + pub priority_owner_id: Option<u64>, + /// search only for repos that belong to the given team id + pub team_id: Option<u64>, + /// search only for repos that the user with the given id has starred + pub starred_by: Option<u64>, + /// include private repositories this user has access to (defaults to true) + pub private: Option<bool>, + /// show only pubic, private or all repositories (defaults to all) + pub is_private: Option<bool>, + /// include template repositories this user has access to (defaults to true) + pub template: Option<bool>, + /// show only archived, non-archived or all repositories (defaults to all) + pub archived: Option<bool>, + /// type of repository to search for. Supported values are "fork", "source", "mirror" and "collaborative" + pub mode: Option<String>, + /// if `uid` is given, search only for repos that the user owns + pub exclusive: Option<bool>, + /// sort repos by attribute. Supported values are "alpha", "created", "updated", "size", "git_size", "lfs_size", "stars", "forks" and "id". Default is "alpha" + pub sort: Option<String>, + /// sort order, either "asc" (ascending) or "desc" (descending). Default is "asc", ignored if "sort" is not specified. + pub order: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoSearchQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(topic) = &self.topic { + write!(f, "topic={topic}&")?; + } + if let Some(include_desc) = &self.include_desc { + write!(f, "includeDesc={include_desc}&")?; + } + if let Some(uid) = &self.uid { + write!(f, "uid={uid}&")?; + } + if let Some(priority_owner_id) = &self.priority_owner_id { + write!(f, "priority_owner_id={priority_owner_id}&")?; + } + if let Some(team_id) = &self.team_id { + write!(f, "team_id={team_id}&")?; + } + if let Some(starred_by) = &self.starred_by { + write!(f, "starredBy={starred_by}&")?; + } + if let Some(private) = &self.private { + write!(f, "private={private}&")?; + } + if let Some(is_private) = &self.is_private { + write!(f, "is_private={is_private}&")?; + } + if let Some(template) = &self.template { + write!(f, "template={template}&")?; + } + if let Some(archived) = &self.archived { + write!(f, "archived={archived}&")?; + } + if let Some(mode) = &self.mode { + write!(f, "mode={mode}&")?; + } + if let Some(exclusive) = &self.exclusive { + write!(f, "exclusive={exclusive}&")?; + } + if let Some(sort) = &self.sort { + write!(f, "sort={sort}&")?; + } + if let Some(order) = &self.order { + write!(f, "order={order}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListActionsSecretsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListActionsSecretsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct ListActionTasksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results, default maximum page size is 50 + pub limit: Option<u32>, +} + +impl std::fmt::Display for ListActionTasksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct GetRepoVariablesListQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for GetRepoVariablesListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListActivityFeedsQuery { + /// the date of the activities to be found + pub date: Option<time::Date>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListActivityFeedsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(date) = &self.date { + write!( + f, + "date={field_name}&", + field_name = date + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListBranchesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListBranchesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListCollaboratorsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListCollaboratorsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetAllCommitsQuery { + /// SHA or branch to start listing commits from (usually 'master') + pub sha: Option<String>, + /// filepath of a file/dir + pub path: Option<String>, + /// include diff stats for every commit (disable for speedup, default 'true') + pub stat: Option<bool>, + /// include verification for every commit (disable for speedup, default 'true') + pub verification: Option<bool>, + /// include a list of affected files for every commit (disable for speedup, default 'true') + pub files: Option<bool>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results (ignored if used with 'path') + pub limit: Option<u32>, + /// commits that match the given specifier will not be listed. + pub not: Option<String>, +} + +impl std::fmt::Display for RepoGetAllCommitsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(sha) = &self.sha { + write!(f, "sha={sha}&")?; + } + if let Some(path) = &self.path { + write!(f, "path={path}&")?; + } + if let Some(stat) = &self.stat { + write!(f, "stat={stat}&")?; + } + if let Some(verification) = &self.verification { + write!(f, "verification={verification}&")?; + } + if let Some(files) = &self.files { + write!(f, "files={files}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(not) = &self.not { + write!(f, "not={not}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetCombinedStatusByRefQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoGetCombinedStatusByRefQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListStatusesByRefQuery { + /// type of sort + pub sort: Option<RepoListStatusesByRefQuerySort>, + /// type of state + pub state: Option<RepoListStatusesByRefQueryState>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListStatusesByRefQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(sort) = &self.sort { + write!(f, "sort={}&", sort.as_str())?; + } + if let Some(state) = &self.state { + write!(f, "state={}&", state.as_str())?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListStatusesByRefQuerySort { + #[serde(rename = "oldest")] + Oldest, + #[serde(rename = "recentupdate")] + Recentupdate, + #[serde(rename = "leastupdate")] + Leastupdate, + #[serde(rename = "leastindex")] + Leastindex, + #[serde(rename = "highestindex")] + Highestindex, +} + +impl RepoListStatusesByRefQuerySort { + fn as_str(&self) -> &'static str { + match self { + RepoListStatusesByRefQuerySort::Oldest => "oldest", + RepoListStatusesByRefQuerySort::Recentupdate => "recentupdate", + RepoListStatusesByRefQuerySort::Leastupdate => "leastupdate", + RepoListStatusesByRefQuerySort::Leastindex => "leastindex", + RepoListStatusesByRefQuerySort::Highestindex => "highestindex", + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListStatusesByRefQueryState { + #[serde(rename = "pending")] + Pending, + #[serde(rename = "success")] + Success, + #[serde(rename = "error")] + Error, + #[serde(rename = "failure")] + Failure, + #[serde(rename = "warning")] + Warning, +} + +impl RepoListStatusesByRefQueryState { + fn as_str(&self) -> &'static str { + match self { + RepoListStatusesByRefQueryState::Pending => "pending", + RepoListStatusesByRefQueryState::Success => "success", + RepoListStatusesByRefQueryState::Error => "error", + RepoListStatusesByRefQueryState::Failure => "failure", + RepoListStatusesByRefQueryState::Warning => "warning", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetContentsListQuery { + /// The name of the commit/branch/tag. Default the repository’s default branch (usually master) + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoGetContentsListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetContentsQuery { + /// The name of the commit/branch/tag. Default the repository’s default branch (usually master) + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoGetContentsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetEditorConfigQuery { + /// The name of the commit/branch/tag. Default the repository’s default branch (usually master) + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoGetEditorConfigQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct ListForksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for ListForksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetSingleCommitQuery { + /// include diff stats for every commit (disable for speedup, default 'true') + pub stat: Option<bool>, + /// include verification for every commit (disable for speedup, default 'true') + pub verification: Option<bool>, + /// include a list of affected files for every commit (disable for speedup, default 'true') + pub files: Option<bool>, +} + +impl std::fmt::Display for RepoGetSingleCommitQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(stat) = &self.stat { + write!(f, "stat={stat}&")?; + } + if let Some(verification) = &self.verification { + write!(f, "verification={verification}&")?; + } + if let Some(files) = &self.files { + write!(f, "files={files}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetNoteQuery { + /// include verification for every commit (disable for speedup, default 'true') + pub verification: Option<bool>, + /// include a list of affected files for every commit (disable for speedup, default 'true') + pub files: Option<bool>, +} + +impl std::fmt::Display for RepoGetNoteQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(verification) = &self.verification { + write!(f, "verification={verification}&")?; + } + if let Some(files) = &self.files { + write!(f, "files={files}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct GetTreeQuery { + /// show all directories and files + pub recursive: Option<bool>, + /// page number; the 'truncated' field in the response will be true if there are still more items after this page, false if the last page + pub page: Option<u32>, + /// number of items per page + pub per_page: Option<u32>, +} + +impl std::fmt::Display for GetTreeQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(recursive) = &self.recursive { + write!(f, "recursive={recursive}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(per_page) = &self.per_page { + write!(f, "per_page={per_page}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListHooksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListHooksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoTestHookQuery { + /// The name of the commit/branch/tag, indicates which commit will be loaded to the webhook payload. + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoTestHookQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueListIssuesQuery { + /// whether issue is open or closed + pub state: Option<IssueListIssuesQueryState>, + /// comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded + pub labels: Option<String>, + /// search string + pub q: Option<String>, + /// filter by type (issues / pulls) if set + pub r#type: Option<IssueListIssuesQueryType>, + /// comma separated list of milestone names or ids. It uses names and fall back to ids. Fetch only issues that have any of this milestones. Non existent milestones are discarded + pub milestones: Option<String>, + /// Only show items updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show items updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// Only show items which were created by the given user + pub created_by: Option<String>, + /// Only show items for which the given user is assigned + pub assigned_by: Option<String>, + /// Only show items in which the given user was mentioned + pub mentioned_by: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueListIssuesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(state) = &self.state { + write!(f, "state={}&", state.as_str())?; + } + if let Some(labels) = &self.labels { + write!(f, "labels={labels}&")?; + } + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(r#type) = &self.r#type { + write!(f, "type={}&", r#type.as_str())?; + } + if let Some(milestones) = &self.milestones { + write!(f, "milestones={milestones}&")?; + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(created_by) = &self.created_by { + write!(f, "created_by={created_by}&")?; + } + if let Some(assigned_by) = &self.assigned_by { + write!(f, "assigned_by={assigned_by}&")?; + } + if let Some(mentioned_by) = &self.mentioned_by { + write!(f, "mentioned_by={mentioned_by}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum IssueListIssuesQueryState { + #[serde(rename = "closed")] + Closed, + #[serde(rename = "open")] + Open, + #[serde(rename = "all")] + All, +} + +impl IssueListIssuesQueryState { + fn as_str(&self) -> &'static str { + match self { + IssueListIssuesQueryState::Closed => "closed", + IssueListIssuesQueryState::Open => "open", + IssueListIssuesQueryState::All => "all", + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum IssueListIssuesQueryType { + #[serde(rename = "issues")] + Issues, + #[serde(rename = "pulls")] + Pulls, +} + +impl IssueListIssuesQueryType { + fn as_str(&self) -> &'static str { + match self { + IssueListIssuesQueryType::Issues => "issues", + IssueListIssuesQueryType::Pulls => "pulls", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueGetRepoCommentsQuery { + /// if provided, only comments updated since the provided time are returned. + pub since: Option<time::OffsetDateTime>, + /// if provided, only comments updated before the provided time are returned. + pub before: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueGetRepoCommentsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueCreateIssueCommentAttachmentQuery { + /// name of the attachment + pub name: Option<String>, + /// time of the attachment's creation. This is a timestamp in RFC 3339 format + pub updated_at: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for IssueCreateIssueCommentAttachmentQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(name) = &self.name { + write!(f, "name={name}&")?; + } + if let Some(updated_at) = &self.updated_at { + write!( + f, + "updated_at={field_name}&", + field_name = updated_at + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueCreateIssueAttachmentQuery { + /// name of the attachment + pub name: Option<String>, + /// time of the attachment's creation. This is a timestamp in RFC 3339 format + pub updated_at: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for IssueCreateIssueAttachmentQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(name) = &self.name { + write!(f, "name={name}&")?; + } + if let Some(updated_at) = &self.updated_at { + write!( + f, + "updated_at={field_name}&", + field_name = updated_at + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueListBlocksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueListBlocksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueGetCommentsQuery { + /// if provided, only comments updated since the specified time are returned. + pub since: Option<time::OffsetDateTime>, + /// if provided, only comments updated before the provided time are returned. + pub before: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for IssueGetCommentsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueListIssueDependenciesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueListIssueDependenciesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueGetIssueReactionsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueGetIssueReactionsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueSubscriptionsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueSubscriptionsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueGetCommentsAndTimelineQuery { + /// if provided, only comments updated since the specified time are returned. + pub since: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, + /// if provided, only comments updated before the provided time are returned. + pub before: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for IssueGetCommentsAndTimelineQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueTrackedTimesQuery { + /// optional filter by user (available for issue managers) + pub user: Option<String>, + /// Only show times updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show times updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueTrackedTimesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(user) = &self.user { + write!(f, "user={user}&")?; + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListKeysQuery { + /// the key_id to search for + pub key_id: Option<u32>, + /// fingerprint of the key + pub fingerprint: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListKeysQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(key_id) = &self.key_id { + write!(f, "key_id={key_id}&")?; + } + if let Some(fingerprint) = &self.fingerprint { + write!(f, "fingerprint={fingerprint}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueListLabelsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueListLabelsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetRawFileOrLfsQuery { + /// The name of the commit/branch/tag. Default the repository’s default branch (usually master) + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoGetRawFileOrLfsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct IssueGetMilestonesListQuery { + /// Milestone state, Recognized values are open, closed and all. Defaults to "open" + pub state: Option<String>, + /// filter by milestone name + pub name: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for IssueGetMilestonesListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(state) = &self.state { + write!(f, "state={state}&")?; + } + if let Some(name) = &self.name { + write!(f, "name={name}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct NotifyGetRepoListQuery { + /// If true, show notifications marked as read. Default value is false + pub all: Option<bool>, + /// Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned + pub status_types: Option<Vec<String>>, + /// filter notifications by subject type + pub subject_type: Option<Vec<NotifyGetRepoListQuerySubjectType>>, + /// Only show notifications updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show notifications updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for NotifyGetRepoListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(all) = &self.all { + write!(f, "all={all}&")?; + } + if let Some(status_types) = &self.status_types { + if !status_types.is_empty() { + for item in status_types { + write!(f, "status-types=")?; + write!(f, "{item}")?; + write!(f, "&")?; + } + } + } + if let Some(subject_type) = &self.subject_type { + if !subject_type.is_empty() { + for item in subject_type { + write!(f, "subject-type=")?; + write!(f, "{}", item.as_str())?; + write!(f, "&")?; + } + } + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum NotifyGetRepoListQuerySubjectType { + #[serde(rename = "issue")] + Issue, + #[serde(rename = "pull")] + Pull, + #[serde(rename = "commit")] + Commit, + #[serde(rename = "repository")] + Repository, +} + +impl NotifyGetRepoListQuerySubjectType { + fn as_str(&self) -> &'static str { + match self { + NotifyGetRepoListQuerySubjectType::Issue => "issue", + NotifyGetRepoListQuerySubjectType::Pull => "pull", + NotifyGetRepoListQuerySubjectType::Commit => "commit", + NotifyGetRepoListQuerySubjectType::Repository => "repository", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct NotifyReadRepoListQuery { + /// If true, mark all notifications on this repo. Default value is false + pub all: Option<String>, + /// Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread. + pub status_types: Option<Vec<String>>, + /// Status to mark notifications as. Defaults to read. + pub to_status: Option<String>, + /// Describes the last point that notifications were checked. Anything updated since this time will not be updated. + pub last_read_at: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for NotifyReadRepoListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(all) = &self.all { + write!(f, "all={all}&")?; + } + if let Some(status_types) = &self.status_types { + if !status_types.is_empty() { + for item in status_types { + write!(f, "status-types=")?; + write!(f, "{item}")?; + write!(f, "&")?; + } + } + } + if let Some(to_status) = &self.to_status { + write!(f, "to-status={to_status}&")?; + } + if let Some(last_read_at) = &self.last_read_at { + write!( + f, + "last_read_at={field_name}&", + field_name = last_read_at + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListPullRequestsQuery { + /// State of pull request: open or closed (optional) + pub state: Option<RepoListPullRequestsQueryState>, + /// Type of sort + pub sort: Option<RepoListPullRequestsQuerySort>, + /// ID of the milestone + pub milestone: Option<u64>, + /// Label IDs + pub labels: Option<Vec<u64>>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListPullRequestsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(state) = &self.state { + write!(f, "state={}&", state.as_str())?; + } + if let Some(sort) = &self.sort { + write!(f, "sort={}&", sort.as_str())?; + } + if let Some(milestone) = &self.milestone { + write!(f, "milestone={milestone}&")?; + } + if let Some(labels) = &self.labels { + if !labels.is_empty() { + for item in labels { + write!(f, "labels=")?; + write!(f, "{item}")?; + write!(f, "&")?; + } + } + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListPullRequestsQueryState { + #[serde(rename = "closed")] + Closed, + #[serde(rename = "open")] + Open, + #[serde(rename = "all")] + All, +} + +impl RepoListPullRequestsQueryState { + fn as_str(&self) -> &'static str { + match self { + RepoListPullRequestsQueryState::Closed => "closed", + RepoListPullRequestsQueryState::Open => "open", + RepoListPullRequestsQueryState::All => "all", + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListPullRequestsQuerySort { + #[serde(rename = "oldest")] + Oldest, + #[serde(rename = "recentupdate")] + Recentupdate, + #[serde(rename = "leastupdate")] + Leastupdate, + #[serde(rename = "mostcomment")] + Mostcomment, + #[serde(rename = "leastcomment")] + Leastcomment, + #[serde(rename = "priority")] + Priority, +} + +impl RepoListPullRequestsQuerySort { + fn as_str(&self) -> &'static str { + match self { + RepoListPullRequestsQuerySort::Oldest => "oldest", + RepoListPullRequestsQuerySort::Recentupdate => "recentupdate", + RepoListPullRequestsQuerySort::Leastupdate => "leastupdate", + RepoListPullRequestsQuerySort::Mostcomment => "mostcomment", + RepoListPullRequestsQuerySort::Leastcomment => "leastcomment", + RepoListPullRequestsQuerySort::Priority => "priority", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoDownloadPullDiffOrPatchQuery { + /// whether to include binary file changes. if true, the diff is applicable with `git apply` + pub binary: Option<bool>, +} + +impl std::fmt::Display for RepoDownloadPullDiffOrPatchQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(binary) = &self.binary { + write!(f, "binary={binary}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetPullRequestCommitsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, + /// include verification for every commit (disable for speedup, default 'true') + pub verification: Option<bool>, + /// include a list of affected files for every commit (disable for speedup, default 'true') + pub files: Option<bool>, +} + +impl std::fmt::Display for RepoGetPullRequestCommitsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(verification) = &self.verification { + write!(f, "verification={verification}&")?; + } + if let Some(files) = &self.files { + write!(f, "files={files}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetPullRequestFilesQuery { + /// skip to given file + pub skip_to: Option<String>, + /// whitespace behavior + pub whitespace: Option<RepoGetPullRequestFilesQueryWhitespace>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoGetPullRequestFilesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(skip_to) = &self.skip_to { + write!(f, "skip-to={skip_to}&")?; + } + if let Some(whitespace) = &self.whitespace { + write!(f, "whitespace={}&", whitespace.as_str())?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoGetPullRequestFilesQueryWhitespace { + #[serde(rename = "ignore-all")] + IgnoreAll, + #[serde(rename = "ignore-change")] + IgnoreChange, + #[serde(rename = "ignore-eol")] + IgnoreEol, + #[serde(rename = "show-all")] + ShowAll, +} + +impl RepoGetPullRequestFilesQueryWhitespace { + fn as_str(&self) -> &'static str { + match self { + RepoGetPullRequestFilesQueryWhitespace::IgnoreAll => "ignore-all", + RepoGetPullRequestFilesQueryWhitespace::IgnoreChange => "ignore-change", + RepoGetPullRequestFilesQueryWhitespace::IgnoreEol => "ignore-eol", + RepoGetPullRequestFilesQueryWhitespace::ShowAll => "show-all", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListPullReviewsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListPullReviewsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoUpdatePullRequestQuery { + /// how to update pull request + pub style: Option<RepoUpdatePullRequestQueryStyle>, +} + +impl std::fmt::Display for RepoUpdatePullRequestQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(style) = &self.style { + write!(f, "style={}&", style.as_str())?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoUpdatePullRequestQueryStyle { + #[serde(rename = "merge")] + Merge, + #[serde(rename = "rebase")] + Rebase, +} + +impl RepoUpdatePullRequestQueryStyle { + fn as_str(&self) -> &'static str { + match self { + RepoUpdatePullRequestQueryStyle::Merge => "merge", + RepoUpdatePullRequestQueryStyle::Rebase => "rebase", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListPushMirrorsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListPushMirrorsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetRawFileQuery { + /// The name of the commit/branch/tag. Default the repository’s default branch (usually master) + pub r#ref: Option<String>, +} + +impl std::fmt::Display for RepoGetRawFileQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(r#ref) = &self.r#ref { + write!(f, "ref={ref}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListReleasesQuery { + /// filter (exclude / include) drafts, if you dont have repo write access none will show + pub draft: Option<bool>, + /// filter (exclude / include) pre-releases + pub pre_release: Option<bool>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListReleasesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(draft) = &self.draft { + write!(f, "draft={draft}&")?; + } + if let Some(pre_release) = &self.pre_release { + write!(f, "pre-release={pre_release}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoCreateReleaseAttachmentQuery { + /// name of the attachment + pub name: Option<String>, +} + +impl std::fmt::Display for RepoCreateReleaseAttachmentQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(name) = &self.name { + write!(f, "name={name}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListStargazersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListStargazersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListStatusesQuery { + /// type of sort + pub sort: Option<RepoListStatusesQuerySort>, + /// type of state + pub state: Option<RepoListStatusesQueryState>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListStatusesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(sort) = &self.sort { + write!(f, "sort={}&", sort.as_str())?; + } + if let Some(state) = &self.state { + write!(f, "state={}&", state.as_str())?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListStatusesQuerySort { + #[serde(rename = "oldest")] + Oldest, + #[serde(rename = "recentupdate")] + Recentupdate, + #[serde(rename = "leastupdate")] + Leastupdate, + #[serde(rename = "leastindex")] + Leastindex, + #[serde(rename = "highestindex")] + Highestindex, +} + +impl RepoListStatusesQuerySort { + fn as_str(&self) -> &'static str { + match self { + RepoListStatusesQuerySort::Oldest => "oldest", + RepoListStatusesQuerySort::Recentupdate => "recentupdate", + RepoListStatusesQuerySort::Leastupdate => "leastupdate", + RepoListStatusesQuerySort::Leastindex => "leastindex", + RepoListStatusesQuerySort::Highestindex => "highestindex", + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub enum RepoListStatusesQueryState { + #[serde(rename = "pending")] + Pending, + #[serde(rename = "success")] + Success, + #[serde(rename = "error")] + Error, + #[serde(rename = "failure")] + Failure, + #[serde(rename = "warning")] + Warning, +} + +impl RepoListStatusesQueryState { + fn as_str(&self) -> &'static str { + match self { + RepoListStatusesQueryState::Pending => "pending", + RepoListStatusesQueryState::Success => "success", + RepoListStatusesQueryState::Error => "error", + RepoListStatusesQueryState::Failure => "failure", + RepoListStatusesQueryState::Warning => "warning", + } + } +} +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListSubscribersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListSubscribersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListTagsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results, default maximum page size is 50 + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListTagsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoTrackedTimesQuery { + /// optional filter by user (available for issue managers) + pub user: Option<String>, + /// Only show times updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show times updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoTrackedTimesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(user) = &self.user { + write!(f, "user={user}&")?; + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoListTopicsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoListTopicsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetWikiPagesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for RepoGetWikiPagesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct RepoGetWikiPageRevisionsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, +} + +impl std::fmt::Display for RepoGetWikiPageRevisionsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListTeamActivityFeedsQuery { + /// the date of the activities to be found + pub date: Option<time::Date>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListTeamActivityFeedsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(date) = &self.date { + write!( + f, + "date={field_name}&", + field_name = date + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListTeamMembersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListTeamMembersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListTeamReposQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListTeamReposQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq)] +pub struct TopicSearchQuery { + /// keywords to search + pub q: String, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for TopicSearchQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let q = &self.q; + write!(f, "q={q}&")?; + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct GetUserVariablesListQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for GetUserVariablesListQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserGetOAuth2ApplicationsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserGetOAuth2ApplicationsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListFollowersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListFollowersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListFollowingQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListFollowingQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListGpgKeysQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListGpgKeysQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListHooksQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListHooksQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListKeysQuery { + /// fingerprint of the key + pub fingerprint: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListKeysQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(fingerprint) = &self.fingerprint { + write!(f, "fingerprint={fingerprint}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListBlockedUsersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListBlockedUsersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListCurrentUserOrgsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListCurrentUserOrgsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListReposQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListReposQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListStarredQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListStarredQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserGetStopWatchesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserGetStopWatchesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentListSubscriptionsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserCurrentListSubscriptionsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListTeamsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListTeamsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserCurrentTrackedTimesQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, + /// Only show times updated after the given time. This is a timestamp in RFC 3339 format + pub since: Option<time::OffsetDateTime>, + /// Only show times updated before the given time. This is a timestamp in RFC 3339 format + pub before: Option<time::OffsetDateTime>, +} + +impl std::fmt::Display for UserCurrentTrackedTimesQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + if let Some(since) = &self.since { + write!( + f, + "since={field_name}&", + field_name = since + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(before) = &self.before { + write!( + f, + "before={field_name}&", + field_name = before + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserSearchQuery { + /// keyword + pub q: Option<String>, + /// ID of the user to search for + pub uid: Option<u64>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserSearchQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(q) = &self.q { + write!(f, "q={q}&")?; + } + if let Some(uid) = &self.uid { + write!(f, "uid={uid}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} +#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] +pub struct UserSearchResponse { + pub data: Option<Vec<User>>, + pub ok: Option<bool>, +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListActivityFeedsQuery { + /// if true, only show actions performed by the requested user + pub only_performed_by: Option<bool>, + /// the date of the activities to be found + pub date: Option<time::Date>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListActivityFeedsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(only_performed_by) = &self.only_performed_by { + write!(f, "only-performed-by={only_performed_by}&")?; + } + if let Some(date) = &self.date { + write!( + f, + "date={field_name}&", + field_name = date + .format(&time::format_description::well_known::Rfc3339) + .unwrap() + )?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListFollowersQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListFollowersQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListFollowingQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListFollowingQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListGpgKeysQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListGpgKeysQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListKeysQuery { + /// fingerprint of the key + pub fingerprint: Option<String>, + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListKeysQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(fingerprint) = &self.fingerprint { + write!(f, "fingerprint={fingerprint}&")?; + } + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct OrgListUserOrgsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for OrgListUserOrgsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListReposQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListReposQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListStarredQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListStarredQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserListSubscriptionsQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserListSubscriptionsQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} + +#[derive(Debug, Clone, PartialEq, Default)] +pub struct UserGetTokensQuery { + /// page number of results to return (1-based) + pub page: Option<u32>, + /// page size of results + pub limit: Option<u32>, +} + +impl std::fmt::Display for UserGetTokensQuery { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if let Some(page) = &self.page { + write!(f, "page={page}&")?; + } + if let Some(limit) = &self.limit { + write!(f, "limit={limit}&")?; + } + + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..abbb8a5 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,437 @@ +use reqwest::{Client, Request, StatusCode}; +use serde::{Deserialize, Deserializer}; +use soft_assert::*; +use url::Url; +use zeroize::Zeroize; + +pub struct Forgejo { + url: Url, + client: Client, +} + +mod generated; + +#[derive(thiserror::Error, Debug)] +pub enum ForgejoError { + #[error("url must have a host")] + HostRequired, + #[error("scheme must be http or https")] + HttpRequired, + #[error(transparent)] + ReqwestError(#[from] reqwest::Error), + #[error("API key should be ascii")] + KeyNotAscii, + #[error("the response from forgejo was not properly structured")] + BadStructure(#[from] StructureError), + #[error("unexpected status code {} {}", .0.as_u16(), .0.canonical_reason().unwrap_or(""))] + UnexpectedStatusCode(StatusCode), + #[error("{} {}{}", .0.as_u16(), .0.canonical_reason().unwrap_or(""), .1.as_ref().map(|s| format!(": {s}")).unwrap_or_default())] + ApiError(StatusCode, Option<String>), + #[error("the provided authorization was too long to accept")] + AuthTooLong, +} + +#[derive(thiserror::Error, Debug)] +pub enum StructureError { + #[error("{contents}")] + Serde { + e: serde_json::Error, + contents: String, + }, + #[error("failed to find header `{0}`")] + HeaderMissing(&'static str), + #[error("header was not ascii")] + HeaderNotAscii, + #[error("failed to parse header")] + HeaderParseFailed, +} + +/// Method of authentication to connect to the Forgejo host with. +pub enum Auth<'a> { + /// Application Access Token. Grants access to scope enabled for the + /// provided token, which may include full access. + /// + /// To learn how to create a token, see + /// [the Codeberg docs on the subject](https://docs.codeberg.org/advanced/access-token/). + /// + /// To learn about token scope, see + /// [the official Forgejo docs](https://forgejo.org/docs/latest/user/token-scope/). + Token(&'a str), + /// OAuth2 Token. Grants full access to the user's account, except for + /// creating application access tokens. + /// + /// To learn how to create an OAuth2 token, see + /// [the official Forgejo docs on the subject](https://forgejo.org/docs/latest/user/oauth2-provider). + OAuth2(&'a str), + /// Username, password, and 2-factor auth code (if enabled). Grants full + /// access to the user's account. + Password { + username: &'a str, + password: &'a str, + mfa: Option<&'a str>, + }, + /// No authentication. Only grants access to access public endpoints. + None, +} + +impl Forgejo { + pub fn new(auth: Auth, url: Url) -> Result<Self, ForgejoError> { + Self::with_user_agent(auth, url, "forgejo-api-rs") + } + + pub fn with_user_agent(auth: Auth, url: Url, user_agent: &str) -> Result<Self, ForgejoError> { + soft_assert!( + matches!(url.scheme(), "http" | "https"), + Err(ForgejoError::HttpRequired) + ); + + let mut headers = reqwest::header::HeaderMap::new(); + match auth { + Auth::Token(token) => { + let mut header: reqwest::header::HeaderValue = format!("token {token}") + .try_into() + .map_err(|_| ForgejoError::KeyNotAscii)?; + header.set_sensitive(true); + headers.insert("Authorization", header); + } + Auth::Password { + username, + password, + mfa, + } => { + let unencoded_len = username.len() + password.len() + 1; + let unpadded_len = unencoded_len + .checked_mul(4) + .ok_or(ForgejoError::AuthTooLong)? + .div_ceil(3); + // round up to next multiple of 4, to account for padding + let len = unpadded_len.div_ceil(4) * 4; + let mut bytes = vec![0; len]; + + // panic safety: len cannot be zero + let mut encoder = base64ct::Encoder::<base64ct::Base64>::new(&mut bytes).unwrap(); + + // panic safety: len will always be enough + encoder.encode(username.as_bytes()).unwrap(); + encoder.encode(b":").unwrap(); + encoder.encode(password.as_bytes()).unwrap(); + + let b64 = encoder.finish().unwrap(); + + let mut header: reqwest::header::HeaderValue = + format!("Basic {b64}").try_into().unwrap(); // panic safety: base64 is always ascii + header.set_sensitive(true); + headers.insert("Authorization", header); + + bytes.zeroize(); + + if let Some(mfa) = mfa { + let mut key_header: reqwest::header::HeaderValue = + mfa.try_into().map_err(|_| ForgejoError::KeyNotAscii)?; + key_header.set_sensitive(true); + headers.insert("X-FORGEJO-OTP", key_header); + } + } + Auth::OAuth2(token) => { + let mut header: reqwest::header::HeaderValue = format!("Bearer {token}") + .try_into() + .map_err(|_| ForgejoError::KeyNotAscii)?; + header.set_sensitive(true); + headers.insert("Authorization", header); + } + Auth::None => (), + } + let client = Client::builder() + .user_agent(user_agent) + .default_headers(headers) + .build()?; + Ok(Self { url, client }) + } + + pub async fn download_release_attachment( + &self, + owner: &str, + repo: &str, + release: u64, + attach: u64, + ) -> Result<bytes::Bytes, ForgejoError> { + let release = self + .repo_get_release_attachment(owner, repo, release, attach) + .await?; + let mut url = self.url.clone(); + url.path_segments_mut() + .unwrap() + .pop_if_empty() + .extend(["attachments", &release.uuid.unwrap().to_string()]); + let request = self.client.get(url).build()?; + Ok(self.execute(request).await?.bytes().await?) + } + + /// Requests a new OAuth2 access token + /// + /// More info at [Forgejo's docs](https://forgejo.org/docs/latest/user/oauth2-provider). + pub async fn oauth_get_access_token( + &self, + body: structs::OAuthTokenRequest<'_>, + ) -> Result<structs::OAuthToken, ForgejoError> { + let url = self.url.join("login/oauth/access_token").unwrap(); + let request = self.client.post(url).json(&body).build()?; + let response = self.execute(request).await?; + match response.status().as_u16() { + 200 => Ok(response.json().await?), + _ => Err(ForgejoError::UnexpectedStatusCode(response.status())), + } + } + + fn get(&self, path: &str) -> reqwest::RequestBuilder { + let url = self.url.join("api/v1/").unwrap().join(path).unwrap(); + self.client.get(url) + } + + fn put(&self, path: &str) -> reqwest::RequestBuilder { + let url = self.url.join("api/v1/").unwrap().join(path).unwrap(); + self.client.put(url) + } + + fn post(&self, path: &str) -> reqwest::RequestBuilder { + let url = self.url.join("api/v1/").unwrap().join(path).unwrap(); + self.client.post(url) + } + + fn delete(&self, path: &str) -> reqwest::RequestBuilder { + let url = self.url.join("api/v1/").unwrap().join(path).unwrap(); + self.client.delete(url) + } + + fn patch(&self, path: &str) -> reqwest::RequestBuilder { + let url = self.url.join("api/v1/").unwrap().join(path).unwrap(); + self.client.patch(url) + } + + async fn execute(&self, request: Request) -> Result<reqwest::Response, ForgejoError> { + let response = self.client.execute(request).await?; + match response.status() { + status if status.is_success() => Ok(response), + status if status.is_client_error() => { + Err(ForgejoError::ApiError(status, maybe_err(response).await)) + } + status => Err(ForgejoError::UnexpectedStatusCode(status)), + } + } +} + +async fn maybe_err(res: reqwest::Response) -> Option<String> { + res.json::<ErrorMessage>().await.ok().map(|e| e.message) +} + +#[derive(serde::Deserialize)] +struct ErrorMessage { + message: String, + // intentionally ignored, no need for now + // url: Url +} + +pub mod structs { + pub use crate::generated::structs::*; + + /// A Request for a new OAuth2 access token + /// + /// More info at [Forgejo's docs](https://forgejo.org/docs/latest/user/oauth2-provider). + #[derive(serde::Serialize)] + #[serde(tag = "grant_type")] + pub enum OAuthTokenRequest<'a> { + /// Request for getting an access code for a confidential app + /// + /// The `code` field must have come from sending the user to + /// `/login/oauth/authorize` in their browser + #[serde(rename = "authorization_code")] + Confidential { + client_id: &'a str, + client_secret: &'a str, + code: &'a str, + redirect_uri: url::Url, + }, + /// Request for getting an access code for a public app + /// + /// The `code` field must have come from sending the user to + /// `/login/oauth/authorize` in their browser + #[serde(rename = "authorization_code")] + Public { + client_id: &'a str, + code_verifier: &'a str, + code: &'a str, + redirect_uri: url::Url, + }, + /// Request for refreshing an access code + #[serde(rename = "refresh_token")] + Refresh { + refresh_token: &'a str, + client_id: &'a str, + client_secret: &'a str, + }, + } + + #[derive(serde::Deserialize)] + pub struct OAuthToken { + pub access_token: String, + pub refresh_token: String, + pub token_type: String, + /// Number of seconds until the access token expires. + pub expires_in: u32, + } +} + +// Forgejo can return blank strings for URLs. This handles that by deserializing +// that as `None` +fn none_if_blank_url<'de, D: serde::Deserializer<'de>>( + deserializer: D, +) -> Result<Option<Url>, D::Error> { + use serde::de::{Error, Unexpected, Visitor}; + use std::fmt; + + struct EmptyUrlVisitor; + + impl<'de> Visitor<'de> for EmptyUrlVisitor { + type Value = Option<Url>; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("option") + } + + #[inline] + fn visit_unit<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_none<E>(self) -> Result<Self::Value, E> + where + E: Error, + { + Ok(None) + } + + #[inline] + fn visit_str<E>(self, s: &str) -> Result<Self::Value, E> + where + E: Error, + { + if s.is_empty() { + return Ok(None); + } + Url::parse(s) + .map_err(|err| { + let err_s = format!("{}", err); + Error::invalid_value(Unexpected::Str(s), &err_s.as_str()) + }) + .map(Some) + } + } + + deserializer.deserialize_str(EmptyUrlVisitor) +} + +#[allow(dead_code)] // not used yet, but it might appear in the future +fn deserialize_ssh_url<'de, D, DE>(deserializer: D) -> Result<Url, DE> +where + D: Deserializer<'de>, + DE: serde::de::Error, +{ + let raw_url: String = String::deserialize(deserializer).map_err(DE::custom)?; + parse_ssh_url(&raw_url).map_err(DE::custom) +} + +fn deserialize_optional_ssh_url<'de, D, DE>(deserializer: D) -> Result<Option<Url>, DE> +where + D: Deserializer<'de>, + DE: serde::de::Error, +{ + let raw_url: Option<String> = Option::deserialize(deserializer).map_err(DE::custom)?; + raw_url + .as_ref() + .map(parse_ssh_url) + .map(|res| res.map_err(DE::custom)) + .transpose() + .or(Ok(None)) +} + +fn requested_reviewers_ignore_null<'de, D, DE>( + deserializer: D, +) -> Result<Option<Vec<structs::User>>, DE> +where + D: Deserializer<'de>, + DE: serde::de::Error, +{ + let list: Option<Vec<Option<structs::User>>> = + Option::deserialize(deserializer).map_err(DE::custom)?; + Ok(list.map(|list| list.into_iter().filter_map(|x| x).collect::<Vec<_>>())) +} + +fn parse_ssh_url(raw_url: &String) -> Result<Url, url::ParseError> { + // in case of a non-standard ssh-port (not 22), the ssh url coming from the forgejo API + // is actually parseable by the url crate, so try to do that first + Url::parse(raw_url).or_else(|_| { + // otherwise the ssh url is not parseable by the url crate and we try again after some + // pre-processing + let url = format!("ssh://{url}", url = raw_url.replace(":", "/")); + Url::parse(url.as_str()) + }) +} + +#[test] +fn ssh_url_deserialization() { + #[derive(serde::Deserialize)] + struct SshUrl { + #[serde(deserialize_with = "deserialize_ssh_url")] + url: url::Url, + } + let full_url = r#"{ "url": "ssh://git@codeberg.org/Cyborus/forgejo-api" }"#; + let ssh_url = r#"{ "url": "git@codeberg.org:Cyborus/forgejo-api" }"#; + + let full_url_de = + serde_json::from_str::<SshUrl>(full_url).expect("failed to deserialize full url"); + let ssh_url_de = + serde_json::from_str::<SshUrl>(ssh_url).expect("failed to deserialize ssh url"); + + let expected = "ssh://git@codeberg.org/Cyborus/forgejo-api"; + assert_eq!(full_url_de.url.as_str(), expected); + assert_eq!(ssh_url_de.url.as_str(), expected); + + #[derive(serde::Deserialize)] + struct OptSshUrl { + #[serde(deserialize_with = "deserialize_optional_ssh_url")] + url: Option<url::Url>, + } + let null_url = r#"{ "url": null }"#; + + let full_url_de = serde_json::from_str::<OptSshUrl>(full_url) + .expect("failed to deserialize optional full url"); + let ssh_url_de = + serde_json::from_str::<OptSshUrl>(ssh_url).expect("failed to deserialize optional ssh url"); + let null_url_de = + serde_json::from_str::<OptSshUrl>(null_url).expect("failed to deserialize null url"); + + let expected = Some("ssh://git@codeberg.org/Cyborus/forgejo-api"); + assert_eq!(full_url_de.url.as_ref().map(|u| u.as_ref()), expected); + assert_eq!(ssh_url_de.url.as_ref().map(|u| u.as_ref()), expected); + assert!(null_url_de.url.is_none()); +} + +impl From<structs::DefaultMergeStyle> for structs::MergePullRequestOptionDo { + fn from(value: structs::DefaultMergeStyle) -> Self { + match value { + structs::DefaultMergeStyle::Merge => structs::MergePullRequestOptionDo::Merge, + structs::DefaultMergeStyle::Rebase => structs::MergePullRequestOptionDo::Rebase, + structs::DefaultMergeStyle::RebaseMerge => { + structs::MergePullRequestOptionDo::RebaseMerge + } + structs::DefaultMergeStyle::Squash => structs::MergePullRequestOptionDo::Squash, + structs::DefaultMergeStyle::FastForwardOnly => { + structs::MergePullRequestOptionDo::FastForwardOnly + } + } + } +} diff --git a/swagger.v1.json b/swagger.v1.json new file mode 100644 index 0000000..4fe69c0 --- /dev/null +++ b/swagger.v1.json @@ -0,0 +1,25101 @@ +{ + "consumes": ["application/json"], + "produces": ["application/json"], + "schemes": ["http", "https"], + "swagger": "2.0", + "info": { + "description": "This documentation describes the Forgejo API.", + "title": "Forgejo API", + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/MIT" + }, + "version": "8.0.0-dev-1514-f9ad844fd6+gitea-1.22.0" + }, + "basePath": "/api/v1", + "paths": { + "/activitypub/repository-id/{repository-id}": { + "get": { + "produces": ["application/json"], + "tags": ["activitypub"], + "summary": "Returns the Repository actor for a repo", + "operationId": "activitypubRepository", + "parameters": [ + { + "type": "integer", + "description": "repository ID of the repo", + "name": "repository-id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityPub" + } + } + } + }, + "/activitypub/repository-id/{repository-id}/inbox": { + "post": { + "produces": ["application/json"], + "tags": ["activitypub"], + "summary": "Send to the inbox", + "operationId": "activitypubRepositoryInbox", + "parameters": [ + { + "type": "integer", + "description": "repository ID of the repo", + "name": "repository-id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/ForgeLike" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + } + }, + "/activitypub/user-id/{user-id}": { + "get": { + "produces": ["application/json"], + "tags": ["activitypub"], + "summary": "Returns the Person actor for a user", + "operationId": "activitypubPerson", + "parameters": [ + { + "type": "integer", + "description": "user ID of the user", + "name": "user-id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityPub" + } + } + } + }, + "/activitypub/user-id/{user-id}/inbox": { + "post": { + "produces": ["application/json"], + "tags": ["activitypub"], + "summary": "Send to the inbox", + "operationId": "activitypubPersonInbox", + "parameters": [ + { + "type": "integer", + "description": "user ID of the user", + "name": "user-id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + } + }, + "/admin/cron": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "List cron tasks", + "operationId": "adminCronList", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CronList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/cron/{task}": { + "post": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Run cron task", + "operationId": "adminCronRun", + "parameters": [ + { + "type": "string", + "description": "task to run", + "name": "task", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/admin/emails": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "List all emails", + "operationId": "adminGetAllEmails", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/EmailList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/emails/search": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Search all emails", + "operationId": "adminSearchEmails", + "parameters": [ + { + "type": "string", + "description": "keyword", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/EmailList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/hooks": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "List system's webhooks", + "operationId": "adminListHooks", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/HookList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Create a hook", + "operationId": "adminCreateHook", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateHookOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Hook" + } + } + } + }, + "/admin/hooks/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Get a hook", + "operationId": "adminGetHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Delete a hook", + "operationId": "adminDeleteHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Update a hook", + "operationId": "adminEditHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to update", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditHookOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + } + } + } + }, + "/admin/orgs": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "List all organizations", + "operationId": "adminGetAllOrgs", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/OrganizationList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/runners/registration-token": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Get an global actions runner registration token", + "operationId": "adminGetRunnerRegistrationToken", + "responses": { + "200": { + "$ref": "#/responses/RegistrationToken" + } + } + } + }, + "/admin/unadopted": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "List unadopted repositories", + "operationId": "adminUnadoptedList", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "pattern of repositories to search for", + "name": "pattern", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/StringSlice" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/unadopted/{owner}/{repo}": { + "post": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Adopt unadopted files as a repository", + "operationId": "adminAdoptRepository", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Delete unadopted files", + "operationId": "adminDeleteUnadoptedRepository", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/admin/users": { + "get": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Search users according filter conditions", + "operationId": "adminSearchUsers", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "ID of the user's login source to search for", + "name": "source_id", + "in": "query" + }, + { + "type": "string", + "description": "user's login name to search for", + "name": "login_name", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Create a user", + "operationId": "adminCreateUser", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateUserOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/User" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/admin/users/{username}": { + "delete": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Delete a user", + "operationId": "adminDeleteUser", + "parameters": [ + { + "type": "string", + "description": "username of user to delete", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "purge the user from the system completely", + "name": "purge", + "in": "query" + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Edit an existing user", + "operationId": "adminEditUser", + "parameters": [ + { + "type": "string", + "description": "username of user to edit", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditUserOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/User" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/admin/users/{username}/keys": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Add a public key on behalf of a user", + "operationId": "adminCreatePublicKey", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "key", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateKeyOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/PublicKey" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/admin/users/{username}/keys/{id}": { + "delete": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Delete a user's public key", + "operationId": "adminDeleteUserPublicKey", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the key to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/admin/users/{username}/orgs": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Create an organization", + "operationId": "adminCreateOrg", + "parameters": [ + { + "type": "string", + "description": "username of the user that will own the created organization", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "organization", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateOrgOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Organization" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/admin/users/{username}/rename": { + "post": { + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Rename a user", + "operationId": "adminRenameUser", + "parameters": [ + { + "type": "string", + "description": "existing username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/RenameUserOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/admin/users/{username}/repos": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["admin"], + "summary": "Create a repository on behalf of a user", + "operationId": "adminCreateRepo", + "parameters": [ + { + "type": "string", + "description": "username of the user. This user will own the created repository", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "repository", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/gitignore/templates": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns a list of all gitignore templates", + "operationId": "listGitignoresTemplates", + "responses": { + "200": { + "$ref": "#/responses/GitignoreTemplateList" + } + } + } + }, + "/gitignore/templates/{name}": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns information about a gitignore template", + "operationId": "getGitignoreTemplateInfo", + "parameters": [ + { + "type": "string", + "description": "name of the template", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitignoreTemplateInfo" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/label/templates": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns a list of all label templates", + "operationId": "listLabelTemplates", + "responses": { + "200": { + "$ref": "#/responses/LabelTemplateList" + } + } + } + }, + "/label/templates/{name}": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns all labels in a template", + "operationId": "getLabelTemplateInfo", + "parameters": [ + { + "type": "string", + "description": "name of the template", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelTemplateInfo" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/licenses": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns a list of all license templates", + "operationId": "listLicenseTemplates", + "responses": { + "200": { + "$ref": "#/responses/LicenseTemplateList" + } + } + } + }, + "/licenses/{name}": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns information about a license template", + "operationId": "getLicenseTemplateInfo", + "parameters": [ + { + "type": "string", + "description": "name of the license", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/LicenseTemplateInfo" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/markdown": { + "post": { + "consumes": ["application/json"], + "produces": ["text/html"], + "tags": ["miscellaneous"], + "summary": "Render a markdown document as HTML", + "operationId": "renderMarkdown", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/MarkdownOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/MarkdownRender" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/markdown/raw": { + "post": { + "consumes": ["text/plain"], + "produces": ["text/html"], + "tags": ["miscellaneous"], + "summary": "Render raw markdown as HTML", + "operationId": "renderMarkdownRaw", + "parameters": [ + { + "description": "Request body to render", + "name": "body", + "in": "body", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/MarkdownRender" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/markup": { + "post": { + "consumes": ["application/json"], + "produces": ["text/html"], + "tags": ["miscellaneous"], + "summary": "Render a markup document as HTML", + "operationId": "renderMarkup", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/MarkupOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/MarkupRender" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/nodeinfo": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns the nodeinfo of the Gitea application", + "operationId": "getNodeInfo", + "responses": { + "200": { + "$ref": "#/responses/NodeInfo" + } + } + } + }, + "/notifications": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "List users's notification threads", + "operationId": "notifyGetList", + "parameters": [ + { + "type": "boolean", + "description": "If true, show notifications marked as read. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned.", + "name": "status-types", + "in": "query" + }, + { + "type": "array", + "items": { + "enum": ["issue", "pull", "commit", "repository"], + "type": "string" + }, + "collectionFormat": "multi", + "description": "filter notifications by subject type", + "name": "subject-type", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/NotificationThreadList" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "Mark notification threads as read, pinned or unread", + "operationId": "notifyReadList", + "parameters": [ + { + "type": "string", + "format": "date-time", + "description": "Describes the last point that notifications were checked. Anything updated since this time will not be updated.", + "name": "last_read_at", + "in": "query" + }, + { + "type": "string", + "description": "If true, mark all notifications on this repo. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread.", + "name": "status-types", + "in": "query" + }, + { + "type": "string", + "description": "Status to mark notifications as, Defaults to read.", + "name": "to-status", + "in": "query" + } + ], + "responses": { + "205": { + "$ref": "#/responses/NotificationThreadList" + } + } + } + }, + "/notifications/new": { + "get": { + "tags": ["notification"], + "summary": "Check if unread notifications exist", + "operationId": "notifyNewAvailable", + "responses": { + "200": { + "$ref": "#/responses/NotificationCount" + } + } + } + }, + "/notifications/threads/{id}": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "Get notification thread by ID", + "operationId": "notifyGetThread", + "parameters": [ + { + "type": "string", + "description": "id of notification thread", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/NotificationThread" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "Mark notification thread as read by ID", + "operationId": "notifyReadThread", + "parameters": [ + { + "type": "string", + "description": "id of notification thread", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "default": "read", + "description": "Status to mark notifications as", + "name": "to-status", + "in": "query" + } + ], + "responses": { + "205": { + "$ref": "#/responses/NotificationThread" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/org/{org}/repos": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create a repository in an organization", + "operationId": "createOrgRepoDeprecated", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "name of organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get list of organizations", + "operationId": "orgGetAll", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/OrganizationList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create an organization", + "operationId": "orgCreate", + "parameters": [ + { + "name": "organization", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateOrgOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Organization" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs/{org}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get an organization", + "operationId": "orgGet", + "parameters": [ + { + "type": "string", + "description": "name of the organization to get", + "name": "org", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Organization" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Delete an organization", + "operationId": "orgDelete", + "parameters": [ + { + "type": "string", + "description": "organization that is to be deleted", + "name": "org", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Edit an organization", + "operationId": "orgEdit", + "parameters": [ + { + "type": "string", + "description": "name of the organization to edit", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/EditOrgOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Organization" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/actions/runners/registration-token": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get an organization's actions runner registration token", + "operationId": "orgGetRunnerRegistrationToken", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RegistrationToken" + } + } + } + }, + "/orgs/{org}/actions/secrets": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's actions secrets", + "operationId": "orgListActionsSecrets", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/SecretList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/actions/secrets/{secretname}": { + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create or Update a secret value in an organization", + "operationId": "updateOrgSecret", + "parameters": [ + { + "type": "string", + "description": "name of organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateOrUpdateSecretOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a secret" + }, + "204": { + "description": "response when updating a secret" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Delete a secret in an organization", + "operationId": "deleteOrgSecret", + "parameters": [ + { + "type": "string", + "description": "name of organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "delete one secret of the organization" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/actions/variables": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get an org-level variables list", + "operationId": "getOrgVariablesList", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/VariableList" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/actions/variables/{variablename}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get an org-level variable", + "operationId": "getOrgVariable", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionVariable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Update an org-level variable", + "operationId": "updateOrgVariable", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when updating an org-level variable" + }, + "204": { + "description": "response when updating an org-level variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create an org-level variable", + "operationId": "createOrgVariable", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating an org-level variable" + }, + "204": { + "description": "response when creating an org-level variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Delete an org-level variable", + "operationId": "deleteOrgVariable", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionVariable" + }, + "201": { + "description": "response when deleting a variable" + }, + "204": { + "description": "response when deleting a variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/activities/feeds": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's activity feeds", + "operationId": "orgListActivityFeeds", + "parameters": [ + { + "type": "string", + "description": "name of the org", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date", + "description": "the date of the activities to be found", + "name": "date", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityFeedsList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/avatar": { + "post": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Update Avatar", + "operationId": "orgUpdateAvatar", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateUserAvatarOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Delete Avatar", + "operationId": "orgDeleteAvatar", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/block/{username}": { + "put": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Blocks a user from the organization", + "operationId": "orgBlockUser", + "parameters": [ + { + "type": "string", + "description": "name of the org", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs/{org}/hooks": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's webhooks", + "operationId": "orgListHooks", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/HookList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create a hook", + "operationId": "orgCreateHook", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateHookOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/hooks/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get a hook", + "operationId": "orgGetHook", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Delete a hook", + "operationId": "orgDeleteHook", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Update a hook", + "operationId": "orgEditHook", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to update", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditHookOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/labels": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's labels", + "operationId": "orgListLabels", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create a label for an organization", + "operationId": "orgCreateLabel", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateLabelOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs/{org}/labels/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get a single label", + "operationId": "orgGetLabel", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["organization"], + "summary": "Delete a label", + "operationId": "orgDeleteLabel", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Update a label", + "operationId": "orgEditLabel", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditLabelOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs/{org}/list_blocked": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List the organization's blocked users", + "operationId": "orgListBlockedUsers", + "parameters": [ + { + "type": "string", + "description": "name of the org", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/BlockedUserList" + } + } + } + }, + "/orgs/{org}/members": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's members", + "operationId": "orgListMembers", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/members/{username}": { + "get": { + "tags": ["organization"], + "summary": "Check if a user is a member of an organization", + "operationId": "orgIsMember", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "user is a member" + }, + "303": { + "description": "redirection to /orgs/{org}/public_members/{username}" + }, + "404": { + "description": "user is not a member" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Remove a member from an organization", + "operationId": "orgDeleteMember", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "member removed" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/public_members": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's public members", + "operationId": "orgListPublicMembers", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/public_members/{username}": { + "get": { + "tags": ["organization"], + "summary": "Check if a user is a public member of an organization", + "operationId": "orgIsPublicMember", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "user is a public member" + }, + "404": { + "description": "user is not a public member" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Publicize a user's membership", + "operationId": "orgPublicizeMember", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "membership publicized" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Conceal a user's membership", + "operationId": "orgConcealMember", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/repos": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's repos", + "operationId": "orgListRepos", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create a repository in an organization", + "operationId": "createOrgRepo", + "parameters": [ + { + "type": "string", + "description": "name of organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/teams": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List an organization's teams", + "operationId": "orgListTeams", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TeamList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Create a team", + "operationId": "orgCreateTeam", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateTeamOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Team" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/orgs/{org}/teams/search": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Search for teams within an organization", + "operationId": "teamSearch", + "parameters": [ + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "keywords to search", + "name": "q", + "in": "query" + }, + { + "type": "boolean", + "description": "include search within team description (defaults to true)", + "name": "include_desc", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "SearchResults of a successful search", + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/Team" + } + }, + "ok": { + "type": "boolean" + } + } + } + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/orgs/{org}/unblock/{username}": { + "put": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Unblock a user from the organization", + "operationId": "orgUnblockUser", + "parameters": [ + { + "type": "string", + "description": "name of the org", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/packages/{owner}": { + "get": { + "produces": ["application/json"], + "tags": ["package"], + "summary": "Gets all packages of an owner", + "operationId": "listPackages", + "parameters": [ + { + "type": "string", + "description": "owner of the packages", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + }, + { + "enum": [ + "alpine", + "cargo", + "chef", + "composer", + "conan", + "conda", + "container", + "cran", + "debian", + "generic", + "go", + "helm", + "maven", + "npm", + "nuget", + "pub", + "pypi", + "rpm", + "rubygems", + "swift", + "vagrant" + ], + "type": "string", + "description": "package type filter", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "name filter", + "name": "q", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PackageList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/packages/{owner}/{type}/{name}/{version}": { + "get": { + "produces": ["application/json"], + "tags": ["package"], + "summary": "Gets a package", + "operationId": "getPackage", + "parameters": [ + { + "type": "string", + "description": "owner of the package", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "type of the package", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the package", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "version of the package", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Package" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["package"], + "summary": "Delete a package", + "operationId": "deletePackage", + "parameters": [ + { + "type": "string", + "description": "owner of the package", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "type of the package", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the package", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "version of the package", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/packages/{owner}/{type}/{name}/{version}/files": { + "get": { + "produces": ["application/json"], + "tags": ["package"], + "summary": "Gets all files of a package", + "operationId": "listPackageFiles", + "parameters": [ + { + "type": "string", + "description": "owner of the package", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "type of the package", + "name": "type", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the package", + "name": "name", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "version of the package", + "name": "version", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PackageFileList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/issues/search": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Search for issues across the repositories that the user has access to", + "operationId": "issueSearchIssues", + "parameters": [ + { + "type": "string", + "description": "whether issue is open or closed", + "name": "state", + "in": "query" + }, + { + "type": "string", + "description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", + "name": "labels", + "in": "query" + }, + { + "type": "string", + "description": "comma separated list of milestone names. Fetch only issues that have any of this milestones. Non existent are discarded", + "name": "milestones", + "in": "query" + }, + { + "type": "string", + "description": "search string", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "repository to prioritize in the results", + "name": "priority_repo_id", + "in": "query" + }, + { + "type": "string", + "description": "filter by type (issues / pulls) if set", + "name": "type", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "boolean", + "description": "filter (issues / pulls) assigned to you, default is false", + "name": "assigned", + "in": "query" + }, + { + "type": "boolean", + "description": "filter (issues / pulls) created by you, default is false", + "name": "created", + "in": "query" + }, + { + "type": "boolean", + "description": "filter (issues / pulls) mentioning you, default is false", + "name": "mentioned", + "in": "query" + }, + { + "type": "boolean", + "description": "filter pulls requesting your review, default is false", + "name": "review_requested", + "in": "query" + }, + { + "type": "boolean", + "description": "filter pulls reviewed by you, default is false", + "name": "reviewed", + "in": "query" + }, + { + "type": "string", + "description": "filter by owner", + "name": "owner", + "in": "query" + }, + { + "type": "string", + "description": "filter by team (requires organization owner parameter to be provided)", + "name": "team", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + } + } + } + }, + "/repos/migrate": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Migrate a remote git repository", + "operationId": "repoMigrate", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/MigrateRepoOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "409": { + "description": "The repository with the same name already exists." + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/search": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Search for repositories", + "operationId": "repoSearch", + "parameters": [ + { + "type": "string", + "description": "keyword", + "name": "q", + "in": "query" + }, + { + "type": "boolean", + "description": "Limit search to repositories with keyword as topic", + "name": "topic", + "in": "query" + }, + { + "type": "boolean", + "description": "include search of keyword within repository description", + "name": "includeDesc", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "search only for repos that the user with the given id owns or contributes to", + "name": "uid", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "repo owner to prioritize in the results", + "name": "priority_owner_id", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "search only for repos that belong to the given team id", + "name": "team_id", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "search only for repos that the user with the given id has starred", + "name": "starredBy", + "in": "query" + }, + { + "type": "boolean", + "description": "include private repositories this user has access to (defaults to true)", + "name": "private", + "in": "query" + }, + { + "type": "boolean", + "description": "show only pubic, private or all repositories (defaults to all)", + "name": "is_private", + "in": "query" + }, + { + "type": "boolean", + "description": "include template repositories this user has access to (defaults to true)", + "name": "template", + "in": "query" + }, + { + "type": "boolean", + "description": "show only archived, non-archived or all repositories (defaults to all)", + "name": "archived", + "in": "query" + }, + { + "type": "string", + "description": "type of repository to search for. Supported values are \"fork\", \"source\", \"mirror\" and \"collaborative\"", + "name": "mode", + "in": "query" + }, + { + "type": "boolean", + "description": "if `uid` is given, search only for repos that the user owns", + "name": "exclusive", + "in": "query" + }, + { + "type": "string", + "description": "sort repos by attribute. Supported values are \"alpha\", \"created\", \"updated\", \"size\", \"git_size\", \"lfs_size\", \"stars\", \"forks\" and \"id\". Default is \"alpha\"", + "name": "sort", + "in": "query" + }, + { + "type": "string", + "description": "sort order, either \"asc\" (ascending) or \"desc\" (descending). Default is \"asc\", ignored if \"sort\" is not specified.", + "name": "order", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/SearchResults" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a repository", + "operationId": "repoGet", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Repository" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a repository", + "operationId": "repoDelete", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to delete", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to delete", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a repository's properties. Only fields that are set will be changed.", + "operationId": "repoEdit", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to edit", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to edit", + "name": "repo", + "in": "path", + "required": true + }, + { + "description": "Properties of a repo that you can edit", + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditRepoOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/actions/secrets": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List an repo's actions secrets", + "operationId": "repoListActionsSecrets", + "parameters": [ + { + "type": "string", + "description": "owner of the repository", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/SecretList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/actions/secrets/{secretname}": { + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create or Update a secret value in a repository", + "operationId": "updateRepoSecret", + "parameters": [ + { + "type": "string", + "description": "owner of the repository", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateOrUpdateSecretOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a secret" + }, + "204": { + "description": "response when updating a secret" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a secret in a repository", + "operationId": "deleteRepoSecret", + "parameters": [ + { + "type": "string", + "description": "owner of the repository", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "delete one secret of the organization" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/actions/tasks": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's action tasks", + "operationId": "ListActionTasks", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results, default maximum page size is 50", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TasksList" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/conflict" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/actions/variables": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get repo-level variables list", + "operationId": "getRepoVariablesList", + "parameters": [ + { + "type": "string", + "description": "name of the owner", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/VariableList" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/actions/variables/{variablename}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a repo-level variable", + "operationId": "getRepoVariable", + "parameters": [ + { + "type": "string", + "description": "name of the owner", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionVariable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Update a repo-level variable", + "operationId": "updateRepoVariable", + "parameters": [ + { + "type": "string", + "description": "name of the owner", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when updating a repo-level variable" + }, + "204": { + "description": "response when updating a repo-level variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a repo-level variable", + "operationId": "createRepoVariable", + "parameters": [ + { + "type": "string", + "description": "name of the owner", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a repo-level variable" + }, + "204": { + "description": "response when creating a repo-level variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a repo-level variable", + "operationId": "deleteRepoVariable", + "parameters": [ + { + "type": "string", + "description": "name of the owner", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repository", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionVariable" + }, + "201": { + "description": "response when deleting a variable" + }, + "204": { + "description": "response when deleting a variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/actions/workflows/{workflowname}/dispatches": { + "post": { + "consumes": ["application/json"], + "tags": ["repository"], + "summary": "Dispatches a workflow", + "operationId": "DispatchWorkflow", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the workflow", + "name": "workflowname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/DispatchWorkflowOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/activities/feeds": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's activity feeds", + "operationId": "repoListActivityFeeds", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date", + "description": "the date of the activities to be found", + "name": "date", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityFeedsList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/archive/{archive}": { + "get": { + "produces": [ + "application/octet-stream", + "application/zip", + "application/gzip" + ], + "tags": ["repository"], + "summary": "Get an archive of a repository", + "operationId": "repoGetArchive", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the git reference for download with attached archive format (e.g. master.zip)", + "name": "archive", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "success" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/assignees": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Return all users that have write access and can be assigned to issues", + "operationId": "repoGetAssignees", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/avatar": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Update avatar", + "operationId": "repoUpdateAvatar", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateRepoAvatarOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete avatar", + "operationId": "repoDeleteAvatar", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/branch_protections": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List branch protections for a repository", + "operationId": "repoListBranchProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/BranchProtectionList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a branch protections for a repository", + "operationId": "repoCreateBranchProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateBranchProtectionOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/BranchProtection" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/branch_protections/{name}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a specific branch protection for the repository", + "operationId": "repoGetBranchProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of protected branch", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/BranchProtection" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a specific branch protection for the repository", + "operationId": "repoDeleteBranchProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of protected branch", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a branch protections for a repository. Only fields that are set will be changed", + "operationId": "repoEditBranchProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of protected branch", + "name": "name", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditBranchProtectionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/BranchProtection" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/branches": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's branches", + "operationId": "repoListBranches", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/BranchList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a branch", + "operationId": "repoCreateBranch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateBranchRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Branch" + }, + "403": { + "description": "The branch is archived or a mirror." + }, + "404": { + "description": "The old branch does not exist." + }, + "409": { + "description": "The branch with the same name already exists." + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/branches/{branch}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Retrieve a specific branch from a repository, including its effective branch protection", + "operationId": "repoGetBranch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "branch to get", + "name": "branch", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Branch" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a specific branch from a repository", + "operationId": "repoDeleteBranch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "branch to delete", + "name": "branch", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/collaborators": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's collaborators", + "operationId": "repoListCollaborators", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/collaborators/{collaborator}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Check if a user is a collaborator of a repository", + "operationId": "repoCheckCollaborator", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the collaborator", + "name": "collaborator", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a collaborator to a repository", + "operationId": "repoAddCollaborator", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the collaborator to add", + "name": "collaborator", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/AddCollaboratorOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a collaborator from a repository", + "operationId": "repoDeleteCollaborator", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the collaborator to delete", + "name": "collaborator", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/collaborators/{collaborator}/permission": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get repository permissions for a user", + "operationId": "repoGetRepoPermissions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the collaborator", + "name": "collaborator", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepoCollaboratorPermission" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/commits": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a list of all commits from a repository", + "operationId": "repoGetAllCommits", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "SHA or branch to start listing commits from (usually 'master')", + "name": "sha", + "in": "query" + }, + { + "type": "string", + "description": "filepath of a file/dir", + "name": "path", + "in": "query" + }, + { + "type": "boolean", + "description": "include diff stats for every commit (disable for speedup, default 'true')", + "name": "stat", + "in": "query" + }, + { + "type": "boolean", + "description": "include verification for every commit (disable for speedup, default 'true')", + "name": "verification", + "in": "query" + }, + { + "type": "boolean", + "description": "include a list of affected files for every commit (disable for speedup, default 'true')", + "name": "files", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results (ignored if used with 'path')", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "description": "commits that match the given specifier will not be listed.", + "name": "not", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommitList" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/EmptyRepository" + } + } + } + }, + "/repos/{owner}/{repo}/commits/{ref}/status": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a commit's combined status, by branch/tag/commit reference", + "operationId": "repoGetCombinedStatusByRef", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of branch/tag/commit", + "name": "ref", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CombinedStatus" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/commits/{ref}/statuses": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a commit's statuses, by branch/tag/commit reference", + "operationId": "repoListStatusesByRef", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of branch/tag/commit", + "name": "ref", + "in": "path", + "required": true + }, + { + "enum": [ + "oldest", + "recentupdate", + "leastupdate", + "leastindex", + "highestindex" + ], + "type": "string", + "description": "type of sort", + "name": "sort", + "in": "query" + }, + { + "enum": ["pending", "success", "error", "failure", "warning"], + "type": "string", + "description": "type of state", + "name": "state", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommitStatusList" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/commits/{sha}/pull": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get the pull request of the commit", + "operationId": "repoGetCommitPullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "SHA of the commit to get", + "name": "sha", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequest" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/compare/{basehead}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get commit comparison information", + "operationId": "repoCompareDiff", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "compare two branches or commits", + "name": "basehead", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Compare" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/contents": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the metadata of all the entries of the root dir", + "operationId": "repoGetContentsList", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ContentsListResponse" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Modify multiple files in a repository", + "operationId": "repoChangeFiles", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/ChangeFilesOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/FilesResponse" + }, + "403": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/contents/{filepath}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir", + "operationId": "repoGetContents", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "path of the dir, file, symlink or submodule in the repo", + "name": "filepath", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ContentsResponse" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Update a file in a repository", + "operationId": "repoUpdateFile", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "path of the file to update", + "name": "filepath", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateFileOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/FileResponse" + }, + "403": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a file in a repository", + "operationId": "repoCreateFile", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "path of the file to create", + "name": "filepath", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateFileOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/FileResponse" + }, + "403": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a file in a repository", + "operationId": "repoDeleteFile", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "path of the file to delete", + "name": "filepath", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DeleteFileOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/FileDeleteResponse" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/diffpatch": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Apply diff patch to repository", + "operationId": "repoApplyDiffPatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/UpdateFileOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/FileResponse" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/editorconfig/{filepath}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get the EditorConfig definitions of a file in a repository", + "operationId": "repoGetEditorConfig", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "filepath of file to get", + "name": "filepath", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + } + ], + "responses": { + "200": { + "description": "success" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/flags": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's flags", + "operationId": "repoListFlags", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/StringSlice" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Replace all flags of a repository", + "operationId": "repoReplaceAllFlags", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/ReplaceFlagsOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Remove all flags from a repository", + "operationId": "repoDeleteAllFlags", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/flags/{flag}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Check if a repository has a given flag", + "operationId": "repoCheckFlag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the flag", + "name": "flag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a flag to a repository", + "operationId": "repoAddFlag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the flag", + "name": "flag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Remove a flag from a repository", + "operationId": "repoDeleteFlag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the flag", + "name": "flag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/forks": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's forks", + "operationId": "listForks", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Fork a repository", + "operationId": "createFork", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to fork", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to fork", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateForkOption" + } + } + ], + "responses": { + "202": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "description": "The repository with the same name already exists." + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/git/blobs/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the blob of a repository.", + "operationId": "GetBlob", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sha of the commit", + "name": "sha", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitBlobResponse" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/git/commits/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a single commit from a repository", + "operationId": "repoGetSingleCommit", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "a git ref or commit sha", + "name": "sha", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "include diff stats for every commit (disable for speedup, default 'true')", + "name": "stat", + "in": "query" + }, + { + "type": "boolean", + "description": "include verification for every commit (disable for speedup, default 'true')", + "name": "verification", + "in": "query" + }, + { + "type": "boolean", + "description": "include a list of affected files for every commit (disable for speedup, default 'true')", + "name": "files", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/Commit" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/git/commits/{sha}.{diffType}": { + "get": { + "produces": ["text/plain"], + "tags": ["repository"], + "summary": "Get a commit's diff or patch", + "operationId": "repoDownloadCommitDiffOrPatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "SHA of the commit to get", + "name": "sha", + "in": "path", + "required": true + }, + { + "enum": ["diff", "patch"], + "type": "string", + "description": "whether the output is diff or patch", + "name": "diffType", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/string" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/git/notes/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a note corresponding to a single commit from a repository", + "operationId": "repoGetNote", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "a git ref or commit sha", + "name": "sha", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "include verification for every commit (disable for speedup, default 'true')", + "name": "verification", + "in": "query" + }, + { + "type": "boolean", + "description": "include a list of affected files for every commit (disable for speedup, default 'true')", + "name": "files", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/Note" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/git/refs": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get specified ref or filtered repository's refs", + "operationId": "repoListAllGitRefs", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ReferenceList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/git/refs/{ref}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get specified ref or filtered repository's refs", + "operationId": "repoListGitRefs", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "part or full name of the ref", + "name": "ref", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ReferenceList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/git/tags/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the tag object of an annotated tag (not lightweight tags)", + "operationId": "GetAnnotatedTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags.", + "name": "sha", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/AnnotatedTag" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/git/trees/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the tree of a repository.", + "operationId": "GetTree", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sha of the commit", + "name": "sha", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "show all directories and files", + "name": "recursive", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number; the 'truncated' field in the response will be true if there are still more items after this page, false if the last page", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "number of items per page", + "name": "per_page", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitTreeResponse" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/hooks": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List the hooks in a repository", + "operationId": "repoListHooks", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/HookList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a hook", + "operationId": "repoCreateHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateHookOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/hooks/git": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List the Git hooks in a repository", + "operationId": "repoListGitHooks", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitHookList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/hooks/git/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a Git hook", + "operationId": "repoGetGitHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitHook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a Git hook in a repository", + "operationId": "repoDeleteGitHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a Git hook in a repository", + "operationId": "repoEditGitHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditGitHookOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/GitHook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/hooks/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a hook", + "operationId": "repoGetHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a hook in a repository", + "operationId": "repoDeleteHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a hook in a repository", + "operationId": "repoEditHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the hook", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditHookOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/hooks/{id}/tests": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Test a push webhook", + "operationId": "repoTestHook", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to test", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag, indicates which commit will be loaded to the webhook payload.", + "name": "ref", + "in": "query" + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issue_config": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Returns the issue config for a repo", + "operationId": "repoGetIssueConfig", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepoIssueConfig" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issue_config/validate": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Returns the validation information for a issue config", + "operationId": "repoValidateIssueConfig", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepoIssueConfigValidation" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issue_templates": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get available issue templates for a repository", + "operationId": "repoGetIssueTemplates", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueTemplates" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List a repository's issues", + "operationId": "issueListIssues", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "enum": ["closed", "open", "all"], + "type": "string", + "description": "whether issue is open or closed", + "name": "state", + "in": "query" + }, + { + "type": "string", + "description": "comma separated list of labels. Fetch only issues that have any of this labels. Non existent labels are discarded", + "name": "labels", + "in": "query" + }, + { + "type": "string", + "description": "search string", + "name": "q", + "in": "query" + }, + { + "enum": ["issues", "pulls"], + "type": "string", + "description": "filter by type (issues / pulls) if set", + "name": "type", + "in": "query" + }, + { + "type": "string", + "description": "comma separated list of milestone names or ids. It uses names and fall back to ids. Fetch only issues that have any of this milestones. Non existent milestones are discarded", + "name": "milestones", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show items updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show items updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "string", + "description": "Only show items which were created by the given user", + "name": "created_by", + "in": "query" + }, + { + "type": "string", + "description": "Only show items for which the given user is assigned", + "name": "assigned_by", + "in": "query" + }, + { + "type": "string", + "description": "Only show items in which the given user was mentioned", + "name": "mentioned_by", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Create an issue. If using deadline only the date will be taken into account, and time of day ignored.", + "operationId": "issueCreateIssue", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateIssueOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Issue" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "412": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/comments": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List all comments in a repository", + "operationId": "issueGetRepoComments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated since the provided time are returned.", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated before the provided time are returned.", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommentList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/comments/{id}": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a comment", + "operationId": "issueGetComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Comment" + }, + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["issue"], + "summary": "Delete a comment", + "operationId": "issueDeleteComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of comment to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Edit a comment", + "operationId": "issueEditComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditIssueCommentOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Comment" + }, + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/comments/{id}/assets": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List comment's attachments", + "operationId": "issueListIssueCommentAttachments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/AttachmentList" + }, + "404": { + "$ref": "#/responses/error" + } + } + }, + "post": { + "consumes": ["multipart/form-data"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Create a comment attachment", + "operationId": "issueCreateIssueCommentAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the attachment", + "name": "name", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "time of the attachment's creation. This is a timestamp in RFC 3339 format", + "name": "updated_at", + "in": "query" + }, + { + "type": "file", + "description": "attachment to upload", + "name": "attachment", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a comment attachment", + "operationId": "issueGetIssueCommentAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to get", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/error" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Delete a comment attachment", + "operationId": "issueDeleteIssueCommentAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to delete", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Edit a comment attachment", + "operationId": "issueEditIssueCommentAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to edit", + "name": "attachment_id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditAttachmentOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/comments/{id}/reactions": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a list of reactions from a comment of an issue", + "operationId": "issueGetCommentReactions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment to edit", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ReactionList" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Add a reaction to a comment of an issue", + "operationId": "issuePostCommentReaction", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "content", + "in": "body", + "schema": { + "$ref": "#/definitions/EditReactionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Reaction" + }, + "201": { + "$ref": "#/responses/Reaction" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Remove a reaction from a comment of an issue", + "operationId": "issueDeleteCommentReaction", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "content", + "in": "body", + "schema": { + "$ref": "#/definitions/EditReactionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/pinned": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's pinned issues", + "operationId": "repoListPinnedIssues", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get an issue", + "operationId": "issueGetIssue", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to get", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Issue" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["issue"], + "summary": "Delete an issue", + "operationId": "issueDelete", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of issue to delete", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Edit an issue. If using deadline only the date will be taken into account, and time of day ignored.", + "operationId": "issueEditIssue", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to edit", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditIssueOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Issue" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "412": { + "$ref": "#/responses/error" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/assets": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List issue's attachments", + "operationId": "issueListIssueAttachments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/AttachmentList" + }, + "404": { + "$ref": "#/responses/error" + } + } + }, + "post": { + "consumes": ["multipart/form-data"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Create an issue attachment", + "operationId": "issueCreateIssueAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the attachment", + "name": "name", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "time of the attachment's creation. This is a timestamp in RFC 3339 format", + "name": "updated_at", + "in": "query" + }, + { + "type": "file", + "description": "attachment to upload", + "name": "attachment", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get an issue attachment", + "operationId": "issueGetIssueAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to get", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/error" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Delete an issue attachment", + "operationId": "issueDeleteIssueAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to delete", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Edit an issue attachment", + "operationId": "issueEditIssueAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to edit", + "name": "attachment_id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditAttachmentOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/blocks": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List issues that are blocked by this issue", + "operationId": "issueListBlocks", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Block the issue given in the body by the issue in path", + "operationId": "issueCreateIssueBlocking", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueMeta" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Issue" + }, + "404": { + "description": "the issue does not exist" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Unblock the issue given in the body by the issue in path", + "operationId": "issueRemoveIssueBlocking", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueMeta" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Issue" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/comments": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List all comments on an issue", + "operationId": "issueGetComments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated since the specified time are returned.", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated before the provided time are returned.", + "name": "before", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommentList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Add a comment to an issue", + "operationId": "issueCreateComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateIssueCommentOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Comment" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/comments/{id}": { + "delete": { + "tags": ["issue"], + "summary": "Delete a comment", + "operationId": "issueDeleteCommentDeprecated", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "this parameter is ignored", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of comment to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Edit a comment", + "operationId": "issueEditCommentDeprecated", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "this parameter is ignored", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditIssueCommentOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Comment" + }, + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/deadline": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "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.", + "operationId": "issueEditIssueDeadline", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to create or update a deadline on", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditDeadlineOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/IssueDeadline" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/dependencies": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List an issue's dependencies, i.e all issues that block this issue.", + "operationId": "issueListIssueDependencies", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/IssueList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Make the issue in the url depend on the issue in the form.", + "operationId": "issueCreateIssueDependencies", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueMeta" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Issue" + }, + "404": { + "description": "the issue does not exist" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Remove an issue dependency", + "operationId": "issueRemoveIssueDependencies", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueMeta" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Issue" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/labels": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get an issue's labels", + "operationId": "issueGetLabels", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Replace an issue's labels", + "operationId": "issueReplaceLabels", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueLabelsOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelList" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Add a label to an issue", + "operationId": "issueAddLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/IssueLabelsOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelList" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Remove all labels from an issue", + "operationId": "issueClearLabels", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/DeleteLabelsOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/labels/{id}": { + "delete": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Remove a label from an issue", + "operationId": "issueRemoveLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to remove", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/DeleteLabelsOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/pin": { + "post": { + "tags": ["issue"], + "summary": "Pin an Issue", + "operationId": "pinIssue", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of issue to pin", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["issue"], + "summary": "Unpin an Issue", + "operationId": "unpinIssue", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of issue to unpin", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/pin/{position}": { + "patch": { + "tags": ["issue"], + "summary": "Moves the Pin to the given Position", + "operationId": "moveIssuePin", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "the new position", + "name": "position", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/reactions": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a list reactions of an issue", + "operationId": "issueGetIssueReactions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ReactionList" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Add a reaction to an issue", + "operationId": "issuePostIssueReaction", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "content", + "in": "body", + "schema": { + "$ref": "#/definitions/EditReactionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Reaction" + }, + "201": { + "$ref": "#/responses/Reaction" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Remove a reaction from an issue", + "operationId": "issueDeleteIssueReaction", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "content", + "in": "body", + "schema": { + "$ref": "#/definitions/EditReactionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/stopwatch/delete": { + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Delete an issue's existing stopwatch.", + "operationId": "issueDeleteStopWatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to stop the stopwatch on", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "description": "Not repo writer, user does not have rights to toggle stopwatch" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "description": "Cannot cancel a non existent stopwatch" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/stopwatch/start": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Start stopwatch on an issue.", + "operationId": "issueStartStopWatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to create the stopwatch on", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/empty" + }, + "403": { + "description": "Not repo writer, user does not have rights to toggle stopwatch" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "description": "Cannot start a stopwatch again if it already exists" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/stopwatch/stop": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Stop an issue's existing stopwatch.", + "operationId": "issueStopStopWatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to stop the stopwatch on", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "$ref": "#/responses/empty" + }, + "403": { + "description": "Not repo writer, user does not have rights to toggle stopwatch" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "description": "Cannot stop a non existent stopwatch" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/subscriptions": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get users who subscribed on an issue.", + "operationId": "issueSubscriptions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/subscriptions/check": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Check if user is subscribed to an issue", + "operationId": "issueCheckSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/WatchInfo" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/subscriptions/{user}": { + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Subscribe user to issue", + "operationId": "issueAddSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "user to subscribe", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Already subscribed" + }, + "201": { + "description": "Successfully Subscribed" + }, + "304": { + "description": "User can only subscribe itself if he is no admin" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Unsubscribe user from issue", + "operationId": "issueDeleteSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "user witch unsubscribe", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "Already unsubscribed" + }, + "201": { + "description": "Successfully Unsubscribed" + }, + "304": { + "description": "User can only subscribe itself if he is no admin" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/timeline": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List all comments and events on an issue", + "operationId": "issueGetCommentsAndTimeline", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated since the specified time are returned.", + "name": "since", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "if provided, only comments updated before the provided time are returned.", + "name": "before", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TimelineList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/times": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "List an issue's tracked times", + "operationId": "issueTrackedTimes", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "optional filter by user (available for issue managers)", + "name": "user", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TrackedTimeList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Add tracked time to a issue", + "operationId": "issueAddTime", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/AddTimeOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/TrackedTime" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Reset a tracked time of an issue", + "operationId": "issueResetTime", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue to add tracked time to", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/issues/{index}/times/{id}": { + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Delete specific tracked time", + "operationId": "issueDeleteTime", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the issue", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of time to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/keys": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's keys", + "operationId": "repoListKeys", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "the key_id to search for", + "name": "key_id", + "in": "query" + }, + { + "type": "string", + "description": "fingerprint of the key", + "name": "fingerprint", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/DeployKeyList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a key to a repository", + "operationId": "repoCreateKey", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateKeyOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/DeployKey" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/keys/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a repository's key by id", + "operationId": "repoGetKey", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the key to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/DeployKey" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["repository"], + "summary": "Delete a key from a repository", + "operationId": "repoDeleteKey", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the key to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/labels": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get all of a repository's labels", + "operationId": "issueListLabels", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/LabelList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Create a label", + "operationId": "issueCreateLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateLabelOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/labels/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a single label", + "operationId": "issueGetLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["issue"], + "summary": "Delete a label", + "operationId": "issueDeleteLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Update a label", + "operationId": "issueEditLabel", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the label to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditLabelOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Label" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/languages": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get languages and number of bytes of code written", + "operationId": "repoGetLanguages", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/LanguageStatistics" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/media/{filepath}": { + "get": { + "produces": ["*/*"], + "tags": ["repository"], + "summary": "Get a file or it's LFS object from a repository", + "operationId": "repoGetRawFileOrLFS", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "filepath of the file to get", + "name": "filepath", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Returns raw file content." + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/milestones": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get all of a repository's opened milestones", + "operationId": "issueGetMilestonesList", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Milestone state, Recognized values are open, closed and all. Defaults to \"open\"", + "name": "state", + "in": "query" + }, + { + "type": "string", + "description": "filter by milestone name", + "name": "name", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/MilestoneList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Create a milestone", + "operationId": "issueCreateMilestone", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateMilestoneOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Milestone" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/milestones/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Get a milestone", + "operationId": "issueGetMilestone", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the milestone to get, identified by ID and if not available by name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Milestone" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["issue"], + "summary": "Delete a milestone", + "operationId": "issueDeleteMilestone", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the milestone to delete, identified by ID and if not available by name", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["issue"], + "summary": "Update a milestone", + "operationId": "issueEditMilestone", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "the milestone to edit, identified by ID and if not available by name", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditMilestoneOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Milestone" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/mirror-sync": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Sync a mirrored repository", + "operationId": "repoMirrorSync", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to sync", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to sync", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/new_pin_allowed": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Returns if new Issue Pins are allowed", + "operationId": "repoNewPinAllowed", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepoNewIssuePinsAllowed" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/notifications": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "List users's notification threads on a specific repo", + "operationId": "notifyGetRepoList", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "If true, show notifications marked as read. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned", + "name": "status-types", + "in": "query" + }, + { + "type": "array", + "items": { + "enum": ["issue", "pull", "commit", "repository"], + "type": "string" + }, + "collectionFormat": "multi", + "description": "filter notifications by subject type", + "name": "subject-type", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show notifications updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/NotificationThreadList" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["notification"], + "summary": "Mark notification threads as read, pinned or unread on a specific repo", + "operationId": "notifyReadRepoList", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "If true, mark all notifications on this repo. Default value is false", + "name": "all", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "string" + }, + "collectionFormat": "multi", + "description": "Mark notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread.", + "name": "status-types", + "in": "query" + }, + { + "type": "string", + "description": "Status to mark notifications as. Defaults to read.", + "name": "to-status", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Describes the last point that notifications were checked. Anything updated since this time will not be updated.", + "name": "last_read_at", + "in": "query" + } + ], + "responses": { + "205": { + "$ref": "#/responses/NotificationThreadList" + } + } + } + }, + "/repos/{owner}/{repo}/pulls": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's pull requests", + "operationId": "repoListPullRequests", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "enum": ["closed", "open", "all"], + "type": "string", + "description": "State of pull request: open or closed (optional)", + "name": "state", + "in": "query" + }, + { + "enum": [ + "oldest", + "recentupdate", + "leastupdate", + "mostcomment", + "leastcomment", + "priority" + ], + "type": "string", + "description": "Type of sort", + "name": "sort", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "ID of the milestone", + "name": "milestone", + "in": "query" + }, + { + "type": "array", + "items": { + "type": "integer", + "format": "uint64" + }, + "collectionFormat": "multi", + "description": "Label IDs", + "name": "labels", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequestList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a pull request", + "operationId": "repoCreatePullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreatePullRequestOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/PullRequest" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/pinned": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's pinned pull requests", + "operationId": "repoListPinnedPullRequests", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequestList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{base}/{head}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a pull request by base and head", + "operationId": "repoGetPullRequestByBaseHead", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "base of the pull request to get", + "name": "base", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "head of the pull request to get", + "name": "head", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequest" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a pull request", + "operationId": "repoGetPullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to get", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullRequest" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Update a pull request. If using deadline only the date will be taken into account, and time of day ignored.", + "operationId": "repoEditPullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to edit", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditPullRequestOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/PullRequest" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/error" + }, + "412": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}.{diffType}": { + "get": { + "produces": ["text/plain"], + "tags": ["repository"], + "summary": "Get a pull request diff or patch", + "operationId": "repoDownloadPullDiffOrPatch", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to get", + "name": "index", + "in": "path", + "required": true + }, + { + "enum": ["diff", "patch"], + "type": "string", + "description": "whether the output is diff or patch", + "name": "diffType", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "whether to include binary file changes. if true, the diff is applicable with `git apply`", + "name": "binary", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/string" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/commits": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get commits for a pull request", + "operationId": "repoGetPullRequestCommits", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to get", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + }, + { + "type": "boolean", + "description": "include verification for every commit (disable for speedup, default 'true')", + "name": "verification", + "in": "query" + }, + { + "type": "boolean", + "description": "include a list of affected files for every commit (disable for speedup, default 'true')", + "name": "files", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommitList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/files": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get changed files for a pull request", + "operationId": "repoGetPullRequestFiles", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to get", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "skip to given file", + "name": "skip-to", + "in": "query" + }, + { + "enum": ["ignore-all", "ignore-change", "ignore-eol", "show-all"], + "type": "string", + "description": "whitespace behavior", + "name": "whitespace", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ChangedFileList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/merge": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Check if a pull request has been merged", + "operationId": "repoPullRequestIsMerged", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "pull request has been merged" + }, + "404": { + "description": "pull request has not been merged" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Merge a pull request", + "operationId": "repoMergePullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to merge", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/MergePullRequestOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/empty" + }, + "409": { + "$ref": "#/responses/error" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Cancel the scheduled auto merge for the given pull request", + "operationId": "repoCancelScheduledAutoMerge", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to merge", + "name": "index", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/requested_reviewers": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "create review requests for a pull request", + "operationId": "repoCreatePullReviewRequests", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PullReviewRequestOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/PullReviewList" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "cancel review requests for a pull request", + "operationId": "repoDeletePullReviewRequests", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/PullReviewRequestOptions" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List all reviews for a pull request", + "operationId": "repoListPullReviews", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReviewList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a review to an pull request", + "operationId": "repoCreatePullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreatePullReviewOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReview" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a specific review for a pull request", + "operationId": "repoGetPullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReview" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Submit a pending review to an pull request", + "operationId": "repoSubmitPullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/SubmitPullReviewOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReview" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a specific review from a pull request", + "operationId": "repoDeletePullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a specific review for a pull request", + "operationId": "repoGetPullReviewComments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReviewCommentList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a new comment to a pull request review", + "operationId": "repoCreatePullReviewComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreatePullReviewCommentOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReviewComment" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a pull review comment", + "operationId": "repoGetPullReviewComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "comment", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReviewComment" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a pull review comment", + "operationId": "repoDeletePullReviewComment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the comment", + "name": "comment", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Dismiss a review for a pull request", + "operationId": "repoDismissPullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/DismissPullReviewOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReview" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/reviews/{id}/undismissals": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Cancel to dismiss a review for a pull request", + "operationId": "repoUnDismissPullReview", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request", + "name": "index", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the review", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PullReview" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/pulls/{index}/update": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Merge PR's baseBranch into headBranch", + "operationId": "repoUpdatePullRequest", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "index of the pull request to get", + "name": "index", + "in": "path", + "required": true + }, + { + "enum": ["merge", "rebase"], + "type": "string", + "description": "how to update pull request", + "name": "style", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/push_mirrors": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get all push mirrors of the repository", + "operationId": "repoListPushMirrors", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PushMirrorList" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "add a push mirror to the repository", + "operationId": "repoAddPushMirror", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreatePushMirrorOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/PushMirror" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/push_mirrors-sync": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Sync all push mirrored repository", + "operationId": "repoPushMirrorSync", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to sync", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to sync", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/empty" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/push_mirrors/{name}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get push mirror of the repository by remoteName", + "operationId": "repoGetPushMirrorByRemoteName", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "remote name of push mirror", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PushMirror" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "deletes a push mirror from a repository by remoteName", + "operationId": "repoDeletePushMirror", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "remote name of the pushMirror", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/raw/{filepath}": { + "get": { + "produces": ["*/*"], + "tags": ["repository"], + "summary": "Get a file from a repository", + "operationId": "repoGetRawFile", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "filepath of the file to get", + "name": "filepath", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "The name of the commit/branch/tag. Default the repository’s default branch (usually master)", + "name": "ref", + "in": "query" + } + ], + "responses": { + "200": { + "description": "Returns raw file content." + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/releases": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's releases", + "operationId": "repoListReleases", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "filter (exclude / include) drafts, if you dont have repo write access none will show", + "name": "draft", + "in": "query" + }, + { + "type": "boolean", + "description": "filter (exclude / include) pre-releases", + "name": "pre-release", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ReleaseList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a release", + "operationId": "repoCreateRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateReleaseOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/releases/latest": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at", + "operationId": "repoGetLatestRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/releases/tags/{tag}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a release by tag name", + "operationId": "repoGetReleaseByTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name of the release to get", + "name": "tag", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["repository"], + "summary": "Delete a release by tag name", + "operationId": "repoDeleteReleaseByTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "tag name of the release to delete", + "name": "tag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/releases/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a release", + "operationId": "repoGetRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["repository"], + "summary": "Delete a release", + "operationId": "repoDeleteRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Update a release", + "operationId": "repoEditRelease", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditReleaseOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Release" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/releases/{id}/assets": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List release's attachments", + "operationId": "repoListReleaseAttachments", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/AttachmentList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["multipart/form-data", "application/octet-stream"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a release attachment", + "operationId": "repoCreateReleaseAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the attachment", + "name": "name", + "in": "query" + }, + { + "type": "file", + "description": "attachment to upload", + "name": "attachment", + "in": "formData" + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a release attachment", + "operationId": "repoGetReleaseAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to get", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a release attachment", + "operationId": "repoDeleteReleaseAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to delete", + "name": "attachment_id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a release attachment", + "operationId": "repoEditReleaseAttachment", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the release", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint64", + "description": "id of the attachment to edit", + "name": "attachment_id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditAttachmentOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Attachment" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/reviewers": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Return all users that can be requested to review in this repo", + "operationId": "repoGetReviewers", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/runners/registration-token": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a repository's actions runner registration token", + "operationId": "repoGetRunnerRegistrationToken", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/RegistrationToken" + } + } + } + }, + "/repos/{owner}/{repo}/signing-key.gpg": { + "get": { + "produces": ["text/plain"], + "tags": ["repository"], + "summary": "Get signing-key.gpg for given repository", + "operationId": "repoSigningKey", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "GPG armored public key", + "schema": { + "type": "string" + } + } + } + } + }, + "/repos/{owner}/{repo}/stargazers": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's stargazers", + "operationId": "repoListStargazers", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/statuses/{sha}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a commit's statuses", + "operationId": "repoListStatuses", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sha of the commit", + "name": "sha", + "in": "path", + "required": true + }, + { + "enum": [ + "oldest", + "recentupdate", + "leastupdate", + "leastindex", + "highestindex" + ], + "type": "string", + "description": "type of sort", + "name": "sort", + "in": "query" + }, + { + "enum": ["pending", "success", "error", "failure", "warning"], + "type": "string", + "description": "type of state", + "name": "state", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/CommitStatusList" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a commit status", + "operationId": "repoCreateStatus", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "sha of the commit", + "name": "sha", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateStatusOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/CommitStatus" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/subscribers": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's watchers", + "operationId": "repoListSubscribers", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/subscription": { + "get": { + "tags": ["repository"], + "summary": "Check if the current user is watching a repo", + "operationId": "userCurrentCheckSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/WatchInfo" + }, + "404": { + "description": "User is not watching this repo or repo do not exist" + } + } + }, + "put": { + "tags": ["repository"], + "summary": "Watch a repo", + "operationId": "userCurrentPutSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/WatchInfo" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["repository"], + "summary": "Unwatch a repo", + "operationId": "userCurrentDeleteSubscription", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/tag_protections": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List tag protections for a repository", + "operationId": "repoListTagProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/TagProtectionList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a tag protections for a repository", + "operationId": "repoCreateTagProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateTagProtectionOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/TagProtection" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/tag_protections/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a specific tag protection for the repository", + "operationId": "repoGetTagProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "id of the tag protect to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/TagProtection" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a specific tag protection for the repository", + "operationId": "repoDeleteTagProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "id of protected tag", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Edit a tag protections for a repository. Only fields that are set will be changed", + "operationId": "repoEditTagProtection", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "id of protected tag", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditTagProtectionOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/TagProtection" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/tags": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's tags", + "operationId": "repoListTags", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results, default maximum page size is 50", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TagList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a new git tag in a repository", + "operationId": "repoCreateTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateTagOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Tag" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/empty" + }, + "409": { + "$ref": "#/responses/conflict" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/tags/{tag}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get the tag of a repository by tag name", + "operationId": "repoGetTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of tag", + "name": "tag", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Tag" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a repository's tag by name", + "operationId": "repoDeleteTag", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of tag to delete", + "name": "tag", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/empty" + }, + "409": { + "$ref": "#/responses/conflict" + }, + "422": { + "$ref": "#/responses/validationError" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/teams": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repository's teams", + "operationId": "repoListTeams", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/TeamList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/teams/{team}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Check if a team is assigned to a repository", + "operationId": "repoCheckTeam", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "team", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Team" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/error" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a team to a repository", + "operationId": "repoAddTeam", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "team", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a team from a repository", + "operationId": "repoDeleteTeam", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "team name", + "name": "team", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "405": { + "$ref": "#/responses/error" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/times": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a repo's tracked times", + "operationId": "repoTrackedTimes", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "optional filter by user (available for issue managers)", + "name": "user", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TrackedTimeList" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/times/{user}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "List a user's tracked times in a repo", + "operationId": "userTrackedTimes", + "deprecated": true, + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of user", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/TrackedTimeList" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/topics": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get list of topics that a repository has", + "operationId": "repoListTopics", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TopicNames" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Replace list of topics for a repository", + "operationId": "repoUpdateTopics", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/RepoTopicOptions" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/invalidTopicsError" + } + } + } + }, + "/repos/{owner}/{repo}/topics/{topic}": { + "put": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Add a topic to a repository", + "operationId": "repoAddTopic", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the topic to add", + "name": "topic", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/invalidTopicsError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Delete a topic from a repository", + "operationId": "repoDeleteTopic", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the topic to delete", + "name": "topic", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/invalidTopicsError" + } + } + } + }, + "/repos/{owner}/{repo}/transfer": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Transfer a repo ownership", + "operationId": "repoTransfer", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to transfer", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to transfer", + "name": "repo", + "in": "path", + "required": true + }, + { + "description": "Transfer Options", + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/TransferRepoOption" + } + } + ], + "responses": { + "202": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repos/{owner}/{repo}/transfer/accept": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Accept a repo transfer", + "operationId": "acceptRepoTransfer", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to transfer", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to transfer", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "202": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/transfer/reject": { + "post": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Reject a repo transfer", + "operationId": "rejectRepoTransfer", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to transfer", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to transfer", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/wiki/new": { + "post": { + "consumes": ["application/json"], + "tags": ["repository"], + "summary": "Create a wiki page", + "operationId": "repoCreateWikiPage", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateWikiPageOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/WikiPage" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/wiki/page/{pageName}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a wiki page", + "operationId": "repoGetWikiPage", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the page", + "name": "pageName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/WikiPage" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["repository"], + "summary": "Delete a wiki page", + "operationId": "repoDeleteWikiPage", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the page", + "name": "pageName", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + }, + "patch": { + "consumes": ["application/json"], + "tags": ["repository"], + "summary": "Edit a wiki page", + "operationId": "repoEditWikiPage", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the page", + "name": "pageName", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateWikiPageOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/WikiPage" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "423": { + "$ref": "#/responses/repoArchivedError" + } + } + } + }, + "/repos/{owner}/{repo}/wiki/pages": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get all wiki pages", + "operationId": "repoGetWikiPages", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/WikiPageList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{owner}/{repo}/wiki/revisions/{pageName}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get revisions of a wiki page", + "operationId": "repoGetWikiPageRevisions", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the page", + "name": "pageName", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/WikiCommitList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/repos/{template_owner}/{template_repo}/generate": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Create a repository using a template", + "operationId": "generateRepo", + "parameters": [ + { + "type": "string", + "description": "name of the template repository owner", + "name": "template_owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the template repository", + "name": "template_repo", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/GenerateRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "409": { + "description": "The repository with the same name already exists." + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/repositories/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "Get a repository by id", + "operationId": "repoGetByID", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the repo to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Repository" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/settings/api": { + "get": { + "produces": ["application/json"], + "tags": ["settings"], + "summary": "Get instance's global settings for api", + "operationId": "getGeneralAPISettings", + "responses": { + "200": { + "$ref": "#/responses/GeneralAPISettings" + } + } + } + }, + "/settings/attachment": { + "get": { + "produces": ["application/json"], + "tags": ["settings"], + "summary": "Get instance's global settings for Attachment", + "operationId": "getGeneralAttachmentSettings", + "responses": { + "200": { + "$ref": "#/responses/GeneralAttachmentSettings" + } + } + } + }, + "/settings/repository": { + "get": { + "produces": ["application/json"], + "tags": ["settings"], + "summary": "Get instance's global settings for repositories", + "operationId": "getGeneralRepositorySettings", + "responses": { + "200": { + "$ref": "#/responses/GeneralRepoSettings" + } + } + } + }, + "/settings/ui": { + "get": { + "produces": ["application/json"], + "tags": ["settings"], + "summary": "Get instance's global settings for ui", + "operationId": "getGeneralUISettings", + "responses": { + "200": { + "$ref": "#/responses/GeneralUISettings" + } + } + } + }, + "/signing-key.gpg": { + "get": { + "produces": ["text/plain"], + "tags": ["miscellaneous"], + "summary": "Get default signing-key.gpg", + "operationId": "getSigningKey", + "responses": { + "200": { + "description": "GPG armored public key", + "schema": { + "type": "string" + } + } + } + } + }, + "/teams/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get a team", + "operationId": "orgGetTeam", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Team" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["organization"], + "summary": "Delete a team", + "operationId": "orgDeleteTeam", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "team deleted" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Edit a team", + "operationId": "orgEditTeam", + "parameters": [ + { + "type": "integer", + "description": "id of the team to edit", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditTeamOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Team" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/teams/{id}/activities/feeds": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a team's activity feeds", + "operationId": "orgListTeamActivityFeeds", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "date", + "description": "the date of the activities to be found", + "name": "date", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityFeedsList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/teams/{id}/members": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a team's members", + "operationId": "orgListTeamMembers", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/teams/{id}/members/{username}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a particular member of team", + "operationId": "orgListTeamMember", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the member to list", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/User" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Add a team member", + "operationId": "orgAddTeamMember", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user to add", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Remove a team member", + "operationId": "orgRemoveTeamMember", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of the user to remove", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/teams/{id}/repos": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a team's repos", + "operationId": "orgListTeamRepos", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/teams/{id}/repos/{org}/{repo}": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a particular repo of team", + "operationId": "orgListTeamRepo", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "organization that owns the repo to list", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to list", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Repository" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Add a repository to a team", + "operationId": "orgAddTeamRepository", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "organization that owns the repo to add", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to add", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "description": "This does not delete the repository, it only removes the repository from the team.", + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Remove a repository from a team", + "operationId": "orgRemoveTeamRepository", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the team", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "organization that owns the repo to remove", + "name": "org", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to remove", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/topics/search": { + "get": { + "produces": ["application/json"], + "tags": ["repository"], + "summary": "search topics via keyword", + "operationId": "topicSearch", + "parameters": [ + { + "type": "string", + "description": "keywords to search", + "name": "q", + "in": "query", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TopicListResponse" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get the authenticated user", + "operationId": "userGetCurrent", + "responses": { + "200": { + "$ref": "#/responses/User" + } + } + } + }, + "/user/actions/runners/registration-token": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get an user's actions runner registration token", + "operationId": "userGetRunnerRegistrationToken", + "responses": { + "200": { + "$ref": "#/responses/RegistrationToken" + } + } + } + }, + "/user/actions/secrets/{secretname}": { + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create or Update a secret value in a user scope", + "operationId": "updateUserSecret", + "parameters": [ + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateOrUpdateSecretOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a secret" + }, + "204": { + "description": "response when updating a secret" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete a secret in a user scope", + "operationId": "deleteUserSecret", + "parameters": [ + { + "type": "string", + "description": "name of the secret", + "name": "secretname", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "delete one secret of the user" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/actions/variables": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get the user-level list of variables which is created by current doer", + "operationId": "getUserVariablesList", + "parameters": [ + { + "type": "integer", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/VariableList" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/actions/variables/{variablename}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a user-level variable which is created by current doer", + "operationId": "getUserVariable", + "parameters": [ + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActionVariable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Update a user-level variable which is created by current doer", + "operationId": "updateUserVariable", + "parameters": [ + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when updating a variable" + }, + "204": { + "description": "response when updating a variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create a user-level variable", + "operationId": "createUserVariable", + "parameters": [ + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateVariableOption" + } + } + ], + "responses": { + "201": { + "description": "response when creating a variable" + }, + "204": { + "description": "response when creating a variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete a user-level variable which is created by current doer", + "operationId": "deleteUserVariable", + "parameters": [ + { + "type": "string", + "description": "name of the variable", + "name": "variablename", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "response when deleting a variable" + }, + "204": { + "description": "response when deleting a variable" + }, + "400": { + "$ref": "#/responses/error" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/applications/oauth2": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's oauth2 applications", + "operationId": "userGetOAuth2Applications", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/OAuth2ApplicationList" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "creates a new OAuth2 application", + "operationId": "userCreateOAuth2Application", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateOAuth2ApplicationOptions" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/OAuth2Application" + }, + "400": { + "$ref": "#/responses/error" + } + } + } + }, + "/user/applications/oauth2/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "get an OAuth2 Application", + "operationId": "userGetOAuth2Application", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "Application ID to be found", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/OAuth2Application" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "delete an OAuth2 Application", + "operationId": "userDeleteOAuth2Application", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "token to be deleted", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "patch": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "update an OAuth2 Application, this includes regenerating the client secret", + "operationId": "userUpdateOAuth2Application", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "application to be updated", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateOAuth2ApplicationOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/OAuth2Application" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/avatar": { + "post": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Update Avatar", + "operationId": "userUpdateAvatar", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UpdateUserAvatarOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete Avatar", + "operationId": "userDeleteAvatar", + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + } + }, + "/user/block/{username}": { + "put": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Blocks a user from the doer.", + "operationId": "userBlockUser", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/user/emails": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's email addresses", + "operationId": "userListEmails", + "responses": { + "200": { + "$ref": "#/responses/EmailList" + } + } + }, + "post": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Add email addresses", + "operationId": "userAddEmail", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateEmailOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/EmailList" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete email addresses", + "operationId": "userDeleteEmail", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/DeleteEmailOption" + } + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/followers": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's followers", + "operationId": "userCurrentListFollowers", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + } + } + } + }, + "/user/following": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the users that the authenticated user is following", + "operationId": "userCurrentListFollowing", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + } + } + } + }, + "/user/following/{username}": { + "get": { + "tags": ["user"], + "summary": "Check whether a user is followed by the authenticated user", + "operationId": "userCurrentCheckFollowing", + "parameters": [ + { + "type": "string", + "description": "username of followed user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "tags": ["user"], + "summary": "Follow a user", + "operationId": "userCurrentPutFollow", + "parameters": [ + { + "type": "string", + "description": "username of user to follow", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["user"], + "summary": "Unfollow a user", + "operationId": "userCurrentDeleteFollow", + "parameters": [ + { + "type": "string", + "description": "username of user to unfollow", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/gpg_key_token": { + "get": { + "produces": ["text/plain"], + "tags": ["user"], + "summary": "Get a Token to verify", + "operationId": "getVerificationToken", + "responses": { + "200": { + "$ref": "#/responses/string" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/gpg_key_verify": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Verify a GPG key", + "operationId": "userVerifyGPGKey", + "responses": { + "201": { + "$ref": "#/responses/GPGKey" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/user/gpg_keys": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's GPG keys", + "operationId": "userCurrentListGPGKeys", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/GPGKeyList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create a GPG key", + "operationId": "userCurrentPostGPGKey", + "parameters": [ + { + "name": "Form", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateGPGKeyOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/GPGKey" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/user/gpg_keys/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a GPG key", + "operationId": "userCurrentGetGPGKey", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of key to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/GPGKey" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Remove a GPG key", + "operationId": "userCurrentDeleteGPGKey", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of key to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/hooks": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's webhooks", + "operationId": "userListHooks", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/HookList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create a hook", + "operationId": "userCreateHook", + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/CreateHookOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Hook" + } + } + } + }, + "/user/hooks/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a hook", + "operationId": "userGetHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete a hook", + "operationId": "userDeleteHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + } + } + }, + "patch": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Update a hook", + "operationId": "userEditHook", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of the hook to update", + "name": "id", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/EditHookOption" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/Hook" + } + } + } + }, + "/user/keys": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's public keys", + "operationId": "userCurrentListKeys", + "parameters": [ + { + "type": "string", + "description": "fingerprint of the key", + "name": "fingerprint", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PublicKeyList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create a public key", + "operationId": "userCurrentPostKey", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateKeyOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/PublicKey" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/user/keys/{id}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a public key", + "operationId": "userCurrentGetKey", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of key to get", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/PublicKey" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Delete a public key", + "operationId": "userCurrentDeleteKey", + "parameters": [ + { + "type": "integer", + "format": "uint64", + "description": "id of key to delete", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/list_blocked": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's blocked users", + "operationId": "userListBlockedUsers", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/BlockedUserList" + } + } + } + }, + "/user/orgs": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List the current user's organizations", + "operationId": "orgListCurrentUserOrgs", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/OrganizationList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/repos": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the repos that the authenticated user owns", + "operationId": "userCurrentListRepos", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["repository", "user"], + "summary": "Create a repository", + "operationId": "createCurrentUserRepo", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateRepoOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/Repository" + }, + "400": { + "$ref": "#/responses/error" + }, + "409": { + "description": "The repository with the same name already exists." + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/user/settings": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get user settings", + "operationId": "getUserSettings", + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + }, + "patch": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Update user settings", + "operationId": "updateUserSettings", + "parameters": [ + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/UserSettingsOptions" + } + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserSettings" + } + } + } + }, + "/user/starred": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "The repos that the authenticated user has starred", + "operationId": "userCurrentListStarred", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + } + } + } + }, + "/user/starred/{owner}/{repo}": { + "get": { + "tags": ["user"], + "summary": "Whether the authenticated is starring the repo", + "operationId": "userCurrentCheckStarring", + "parameters": [ + { + "type": "string", + "description": "owner of the repo", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "put": { + "tags": ["user"], + "summary": "Star the given repo", + "operationId": "userCurrentPutStar", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to star", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to star", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + }, + "delete": { + "tags": ["user"], + "summary": "Unstar the given repo", + "operationId": "userCurrentDeleteStar", + "parameters": [ + { + "type": "string", + "description": "owner of the repo to unstar", + "name": "owner", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the repo to unstar", + "name": "repo", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/user/stopwatches": { + "get": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get list of all existing stopwatches", + "operationId": "userGetStopWatches", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/StopWatchList" + } + } + } + }, + "/user/subscriptions": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List repositories watched by the authenticated user", + "operationId": "userCurrentListSubscriptions", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + } + } + } + }, + "/user/teams": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List all the teams a user belongs to", + "operationId": "userListTeams", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TeamList" + } + } + } + }, + "/user/times": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the current user's tracked times", + "operationId": "userCurrentTrackedTimes", + "parameters": [ + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated after the given time. This is a timestamp in RFC 3339 format", + "name": "since", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Only show times updated before the given time. This is a timestamp in RFC 3339 format", + "name": "before", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/TrackedTimeList" + } + } + } + }, + "/user/unblock/{username}": { + "put": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Unblocks a user from the doer.", + "operationId": "userUnblockUser", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/validationError" + } + } + } + }, + "/users/search": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Search for users", + "operationId": "userSearch", + "parameters": [ + { + "type": "string", + "description": "keyword", + "name": "q", + "in": "query" + }, + { + "type": "integer", + "format": "uint64", + "description": "ID of the user to search for", + "name": "uid", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "description": "SearchResults of a successful search", + "schema": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + }, + "ok": { + "type": "boolean" + } + } + } + } + } + } + }, + "/users/{username}": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a user", + "operationId": "userGet", + "parameters": [ + { + "type": "string", + "description": "username of user to get", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/User" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/activities/feeds": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List a user's activity feeds", + "operationId": "userListActivityFeeds", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "if true, only show actions performed by the requested user", + "name": "only-performed-by", + "in": "query" + }, + { + "type": "string", + "format": "date", + "description": "the date of the activities to be found", + "name": "date", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/ActivityFeedsList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/followers": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the given user's followers", + "operationId": "userListFollowers", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/following": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the users that the given user is following", + "operationId": "userListFollowing", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/following/{target}": { + "get": { + "tags": ["user"], + "summary": "Check if one user is following another user", + "operationId": "userCheckFollowing", + "parameters": [ + { + "type": "string", + "description": "username of following user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "username of followed user", + "name": "target", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/gpg_keys": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the given user's GPG keys", + "operationId": "userListGPGKeys", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/GPGKeyList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/heatmap": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "Get a user's heatmap", + "operationId": "userGetHeatmapData", + "parameters": [ + { + "type": "string", + "description": "username of user to get", + "name": "username", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/UserHeatmapData" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/keys": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the given user's public keys", + "operationId": "userListKeys", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "fingerprint of the key", + "name": "fingerprint", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/PublicKeyList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/orgs": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "List a user's organizations", + "operationId": "orgListUserOrgs", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/OrganizationList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/orgs/{org}/permissions": { + "get": { + "produces": ["application/json"], + "tags": ["organization"], + "summary": "Get user permissions in organization", + "operationId": "orgGetUserPermissions", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "name of the organization", + "name": "org", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "$ref": "#/responses/OrganizationPermissions" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/repos": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the repos owned by the given user", + "operationId": "userListRepos", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/starred": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "The repos that the given user has starred", + "operationId": "userListStarred", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/subscriptions": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the repositories watched by a user", + "operationId": "userListSubscriptions", + "parameters": [ + { + "type": "string", + "description": "username of the user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/RepositoryList" + }, + "404": { + "$ref": "#/responses/notFound" + } + } + } + }, + "/users/{username}/tokens": { + "get": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "List the authenticated user's access tokens", + "operationId": "userGetTokens", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "integer", + "format": "uint32", + "description": "page number of results to return (1-based)", + "name": "page", + "in": "query" + }, + { + "type": "integer", + "format": "uint32", + "description": "page size of results", + "name": "limit", + "in": "query" + } + ], + "responses": { + "200": { + "$ref": "#/responses/AccessTokenList" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + }, + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["user"], + "summary": "Create an access token", + "operationId": "userCreateToken", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "name": "body", + "in": "body", + "schema": { + "$ref": "#/definitions/CreateAccessTokenOption" + } + } + ], + "responses": { + "201": { + "$ref": "#/responses/AccessToken" + }, + "400": { + "$ref": "#/responses/error" + }, + "403": { + "$ref": "#/responses/forbidden" + } + } + } + }, + "/users/{username}/tokens/{token}": { + "delete": { + "produces": ["application/json"], + "tags": ["user"], + "summary": "delete an access token", + "operationId": "userDeleteAccessToken", + "parameters": [ + { + "type": "string", + "description": "username of user", + "name": "username", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "token to be deleted, identified by ID and if not available by name", + "name": "token", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "$ref": "#/responses/empty" + }, + "403": { + "$ref": "#/responses/forbidden" + }, + "404": { + "$ref": "#/responses/notFound" + }, + "422": { + "$ref": "#/responses/error" + } + } + } + }, + "/version": { + "get": { + "produces": ["application/json"], + "tags": ["miscellaneous"], + "summary": "Returns the version of the Gitea application", + "operationId": "getVersion", + "responses": { + "200": { + "$ref": "#/responses/ServerVersion" + } + } + } + } + }, + "definitions": { + "APIError": { + "description": "APIError is an api error with a message", + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "AccessToken": { + "type": "object", + "title": "AccessToken represents an API access token.", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Scopes" + }, + "sha1": { + "type": "string", + "x-go-name": "Token" + }, + "token_last_eight": { + "type": "string", + "x-go-name": "TokenLastEight" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ActionTask": { + "description": "ActionTask represents a ActionTask", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "CreatedAt" + }, + "display_title": { + "type": "string", + "x-go-name": "DisplayTitle" + }, + "event": { + "type": "string", + "x-go-name": "Event" + }, + "head_branch": { + "type": "string", + "x-go-name": "HeadBranch" + }, + "head_sha": { + "type": "string", + "x-go-name": "HeadSHA" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "run_number": { + "type": "integer", + "format": "int64", + "x-go-name": "RunNumber" + }, + "run_started_at": { + "type": "string", + "format": "date-time", + "x-go-name": "RunStartedAt" + }, + "status": { + "type": "string", + "x-go-name": "Status" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "UpdatedAt" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "workflow_id": { + "type": "string", + "x-go-name": "WorkflowID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ActionTaskResponse": { + "description": "ActionTaskResponse returns a ActionTask", + "type": "object", + "properties": { + "total_count": { + "type": "integer", + "format": "int64", + "x-go-name": "TotalCount" + }, + "workflow_runs": { + "type": "array", + "items": { + "$ref": "#/definitions/ActionTask" + }, + "x-go-name": "Entries" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ActionVariable": { + "description": "ActionVariable return value of the query API", + "type": "object", + "properties": { + "data": { + "description": "the value of the variable", + "type": "string", + "x-go-name": "Data" + }, + "name": { + "description": "the name of the variable", + "type": "string", + "x-go-name": "Name" + }, + "owner_id": { + "description": "the owner to which the variable belongs", + "type": "integer", + "format": "int64", + "x-go-name": "OwnerID" + }, + "repo_id": { + "description": "the repository to which the variable belongs", + "type": "integer", + "format": "int64", + "x-go-name": "RepoID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Activity": { + "type": "object", + "properties": { + "act_user": { + "$ref": "#/definitions/User" + }, + "act_user_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ActUserID" + }, + "comment": { + "$ref": "#/definitions/Comment" + }, + "comment_id": { + "type": "integer", + "format": "int64", + "x-go-name": "CommentID" + }, + "content": { + "type": "string", + "x-go-name": "Content" + }, + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "is_private": { + "type": "boolean", + "x-go-name": "IsPrivate" + }, + "op_type": { + "description": "the type of action", + "type": "string", + "enum": [ + "create_repo", + "rename_repo", + "star_repo", + "watch_repo", + "commit_repo", + "create_issue", + "create_pull_request", + "transfer_repo", + "push_tag", + "comment_issue", + "merge_pull_request", + "close_issue", + "reopen_issue", + "close_pull_request", + "reopen_pull_request", + "delete_tag", + "delete_branch", + "mirror_sync_push", + "mirror_sync_create", + "mirror_sync_delete", + "approve_pull_request", + "reject_pull_request", + "comment_pull", + "publish_release", + "pull_review_dismissed", + "pull_request_ready_for_review", + "auto_merge_pull_request" + ], + "x-go-name": "OpType" + }, + "ref_name": { + "type": "string", + "x-go-name": "RefName" + }, + "repo": { + "$ref": "#/definitions/Repository" + }, + "repo_id": { + "type": "integer", + "format": "int64", + "x-go-name": "RepoID" + }, + "user_id": { + "type": "integer", + "format": "int64", + "x-go-name": "UserID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ActivityPub": { + "description": "ActivityPub type", + "type": "object", + "properties": { + "@context": { + "type": "string", + "x-go-name": "Context" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "AddCollaboratorOption": { + "description": "AddCollaboratorOption options when adding a user as a collaborator of a repository", + "type": "object", + "properties": { + "permission": { + "type": "string", + "x-go-name": "Permission" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "AddTimeOption": { + "description": "AddTimeOption options for adding time to an issue", + "type": "object", + "required": ["time"], + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "time": { + "description": "time in seconds", + "type": "integer", + "format": "int64", + "x-go-name": "Time" + }, + "user_name": { + "description": "User who spent the time (optional)", + "type": "string", + "x-go-name": "User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "AnnotatedTag": { + "description": "AnnotatedTag represents an annotated tag", + "type": "object", + "properties": { + "archive_download_count": { + "$ref": "#/definitions/TagArchiveDownloadCount" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "object": { + "$ref": "#/definitions/AnnotatedTagObject" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "tag": { + "type": "string", + "x-go-name": "Tag" + }, + "tagger": { + "$ref": "#/definitions/CommitUser" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "AnnotatedTagObject": { + "description": "AnnotatedTagObject contains meta information of the tag object", + "type": "object", + "properties": { + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Attachment": { + "description": "Attachment a generic attachment", + "type": "object", + "properties": { + "browser_download_url": { + "type": "string", + "format": "url", + "x-go-name": "DownloadURL" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "download_count": { + "type": "integer", + "format": "int64", + "x-go-name": "DownloadCount" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "size": { + "type": "integer", + "format": "int64", + "x-go-name": "Size" + }, + "uuid": { + "type": "string", + "x-go-name": "UUID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "BlockedUser": { + "type": "object", + "title": "BlockedUser represents a blocked user.", + "properties": { + "block_id": { + "type": "integer", + "format": "int64", + "x-go-name": "BlockID" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Branch": { + "description": "Branch represents a repository branch", + "type": "object", + "properties": { + "commit": { + "$ref": "#/definitions/PayloadCommit" + }, + "effective_branch_protection_name": { + "type": "string", + "x-go-name": "EffectiveBranchProtectionName" + }, + "enable_status_check": { + "type": "boolean", + "x-go-name": "EnableStatusCheck" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "protected": { + "type": "boolean", + "x-go-name": "Protected" + }, + "required_approvals": { + "type": "integer", + "format": "int64", + "x-go-name": "RequiredApprovals" + }, + "status_check_contexts": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "StatusCheckContexts" + }, + "user_can_merge": { + "type": "boolean", + "x-go-name": "UserCanMerge" + }, + "user_can_push": { + "type": "boolean", + "x-go-name": "UserCanPush" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "BranchProtection": { + "description": "BranchProtection represents a branch protection for a repository", + "type": "object", + "properties": { + "apply_to_admins": { + "type": "boolean", + "x-go-name": "ApplyToAdmins" + }, + "approvals_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistTeams" + }, + "approvals_whitelist_username": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistUsernames" + }, + "block_on_official_review_requests": { + "type": "boolean", + "x-go-name": "BlockOnOfficialReviewRequests" + }, + "block_on_outdated_branch": { + "type": "boolean", + "x-go-name": "BlockOnOutdatedBranch" + }, + "block_on_rejected_reviews": { + "type": "boolean", + "x-go-name": "BlockOnRejectedReviews" + }, + "branch_name": { + "description": "Deprecated: true", + "type": "string", + "x-go-name": "BranchName" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "dismiss_stale_approvals": { + "type": "boolean", + "x-go-name": "DismissStaleApprovals" + }, + "enable_approvals_whitelist": { + "type": "boolean", + "x-go-name": "EnableApprovalsWhitelist" + }, + "enable_merge_whitelist": { + "type": "boolean", + "x-go-name": "EnableMergeWhitelist" + }, + "enable_push": { + "type": "boolean", + "x-go-name": "EnablePush" + }, + "enable_push_whitelist": { + "type": "boolean", + "x-go-name": "EnablePushWhitelist" + }, + "enable_status_check": { + "type": "boolean", + "x-go-name": "EnableStatusCheck" + }, + "ignore_stale_approvals": { + "type": "boolean", + "x-go-name": "IgnoreStaleApprovals" + }, + "merge_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistTeams" + }, + "merge_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistUsernames" + }, + "protected_file_patterns": { + "type": "string", + "x-go-name": "ProtectedFilePatterns" + }, + "push_whitelist_deploy_keys": { + "type": "boolean", + "x-go-name": "PushWhitelistDeployKeys" + }, + "push_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistTeams" + }, + "push_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistUsernames" + }, + "require_signed_commits": { + "type": "boolean", + "x-go-name": "RequireSignedCommits" + }, + "required_approvals": { + "type": "integer", + "format": "int64", + "x-go-name": "RequiredApprovals" + }, + "rule_name": { + "type": "string", + "x-go-name": "RuleName" + }, + "status_check_contexts": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "StatusCheckContexts" + }, + "unprotected_file_patterns": { + "type": "string", + "x-go-name": "UnprotectedFilePatterns" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ChangeFileOperation": { + "description": "ChangeFileOperation for creating, updating or deleting a file", + "type": "object", + "required": ["operation", "path"], + "properties": { + "content": { + "description": "new or updated file content, must be base64 encoded", + "type": "string", + "x-go-name": "ContentBase64" + }, + "from_path": { + "description": "old path of the file to move", + "type": "string", + "x-go-name": "FromPath" + }, + "operation": { + "description": "indicates what to do with the file", + "type": "string", + "enum": ["create", "update", "delete"], + "x-go-name": "Operation" + }, + "path": { + "description": "path to the existing or new file", + "type": "string", + "x-go-name": "Path" + }, + "sha": { + "description": "sha is the SHA for the file that already exists, required for update or delete", + "type": "string", + "x-go-name": "SHA" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ChangeFilesOptions": { + "description": "ChangeFilesOptions options for creating, updating or deleting multiple files\nNote: `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": "object", + "required": ["files"], + "properties": { + "author": { + "$ref": "#/definitions/Identity" + }, + "branch": { + "description": "branch (optional) to base this file from. if not given, the default branch is used", + "type": "string", + "x-go-name": "BranchName" + }, + "committer": { + "$ref": "#/definitions/Identity" + }, + "dates": { + "$ref": "#/definitions/CommitDateOptions" + }, + "files": { + "description": "list of file operations", + "type": "array", + "items": { + "$ref": "#/definitions/ChangeFileOperation" + }, + "x-go-name": "Files" + }, + "message": { + "description": "message (optional) for the commit of this file. if not supplied, a default message will be used", + "type": "string", + "x-go-name": "Message" + }, + "new_branch": { + "description": "new_branch (optional) will make a new branch from `branch` before creating the file", + "type": "string", + "x-go-name": "NewBranchName" + }, + "signoff": { + "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.", + "type": "boolean", + "x-go-name": "Signoff" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ChangedFile": { + "description": "ChangedFile store information about files affected by the pull request", + "type": "object", + "properties": { + "additions": { + "type": "integer", + "format": "int64", + "x-go-name": "Additions" + }, + "changes": { + "type": "integer", + "format": "int64", + "x-go-name": "Changes" + }, + "contents_url": { + "type": "string", + "format": "url", + "x-go-name": "ContentsURL" + }, + "deletions": { + "type": "integer", + "format": "int64", + "x-go-name": "Deletions" + }, + "filename": { + "type": "string", + "x-go-name": "Filename" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "previous_filename": { + "type": "string", + "x-go-name": "PreviousFilename" + }, + "raw_url": { + "type": "string", + "format": "url", + "x-go-name": "RawURL" + }, + "status": { + "type": "string", + "x-go-name": "Status" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CombinedStatus": { + "description": "CombinedStatus holds the combined state of several statuses for a single commit", + "type": "object", + "properties": { + "commit_url": { + "type": "string", + "format": "url", + "x-go-name": "CommitURL" + }, + "repository": { + "$ref": "#/definitions/Repository" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "state": { + "$ref": "#/definitions/CommitStatusState" + }, + "statuses": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitStatus" + }, + "x-go-name": "Statuses" + }, + "total_count": { + "type": "integer", + "format": "int64", + "x-go-name": "TotalCount" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Comment": { + "description": "Comment represents a comment on a commit or issue", + "type": "object", + "properties": { + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/Attachment" + }, + "x-go-name": "Attachments" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "issue_url": { + "type": "string", + "format": "url", + "x-go-name": "IssueURL" + }, + "original_author": { + "type": "string", + "x-go-name": "OriginalAuthor" + }, + "original_author_id": { + "type": "integer", + "format": "int64", + "x-go-name": "OriginalAuthorID" + }, + "pull_request_url": { + "type": "string", + "format": "url", + "x-go-name": "PRURL" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Commit": { + "type": "object", + "title": "Commit contains information generated from a Git commit.", + "properties": { + "author": { + "$ref": "#/definitions/User" + }, + "commit": { + "$ref": "#/definitions/RepoCommit" + }, + "committer": { + "$ref": "#/definitions/User" + }, + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitAffectedFiles" + }, + "x-go-name": "Files" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "parents": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitMeta" + }, + "x-go-name": "Parents" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "stats": { + "$ref": "#/definitions/CommitStats" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitAffectedFiles": { + "description": "CommitAffectedFiles store information about files affected by the commit", + "type": "object", + "properties": { + "filename": { + "type": "string", + "x-go-name": "Filename" + }, + "status": { + "type": "string", + "x-go-name": "Status" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitDateOptions": { + "description": "CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE", + "type": "object", + "properties": { + "author": { + "type": "string", + "format": "date-time", + "x-go-name": "Author" + }, + "committer": { + "type": "string", + "format": "date-time", + "x-go-name": "Committer" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitMeta": { + "type": "object", + "title": "CommitMeta contains meta information of a commit in terms of API.", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitStats": { + "description": "CommitStats is statistics for a RepoCommit", + "type": "object", + "properties": { + "additions": { + "type": "integer", + "format": "int64", + "x-go-name": "Additions" + }, + "deletions": { + "type": "integer", + "format": "int64", + "x-go-name": "Deletions" + }, + "total": { + "type": "integer", + "format": "int64", + "x-go-name": "Total" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitStatus": { + "description": "CommitStatus holds a single status of a single Commit", + "type": "object", + "properties": { + "context": { + "type": "string", + "x-go-name": "Context" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "creator": { + "$ref": "#/definitions/User" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "status": { + "$ref": "#/definitions/CommitStatusState" + }, + "target_url": { + "type": "string", + "format": "url", + "x-go-name": "TargetURL" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitStatusState": { + "description": "CommitStatusState holds the state of a CommitStatus\nIt can be \"pending\", \"success\", \"error\" and \"failure\"", + "type": "string", + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CommitUser": { + "type": "object", + "title": "CommitUser contains information of a user in the context of a commit.", + "properties": { + "date": { + "type": "string", + "x-go-name": "Date" + }, + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Compare": { + "type": "object", + "title": "Compare represents a comparison between two commits.", + "properties": { + "commits": { + "type": "array", + "items": { + "$ref": "#/definitions/Commit" + }, + "x-go-name": "Commits" + }, + "total_commits": { + "type": "integer", + "format": "int64", + "x-go-name": "TotalCommits" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ContentsResponse": { + "description": "ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content", + "type": "object", + "properties": { + "_links": { + "$ref": "#/definitions/FileLinksResponse" + }, + "content": { + "description": "`content` is populated when `type` is `file`, otherwise null", + "type": "string", + "x-go-name": "Content" + }, + "download_url": { + "type": "string", + "format": "url", + "x-go-name": "DownloadURL" + }, + "encoding": { + "description": "`encoding` is populated when `type` is `file`, otherwise null", + "type": "string", + "x-go-name": "Encoding" + }, + "git_url": { + "type": "string", + "format": "url", + "x-go-name": "GitURL" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "last_commit_sha": { + "type": "string", + "x-go-name": "LastCommitSHA" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "path": { + "type": "string", + "x-go-name": "Path" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "size": { + "type": "integer", + "format": "int64", + "x-go-name": "Size" + }, + "submodule_git_url": { + "description": "`submodule_git_url` is populated when `type` is `submodule`, otherwise null", + "type": "string", + "format": "url", + "x-go-name": "SubmoduleGitURL" + }, + "target": { + "description": "`target` is populated when `type` is `symlink`, otherwise null", + "type": "string", + "x-go-name": "Target" + }, + "type": { + "description": "`type` will be `file`, `dir`, `symlink`, or `submodule`", + "type": "string", + "x-go-name": "Type" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateAccessTokenOption": { + "description": "CreateAccessTokenOption options when create access token", + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string", + "x-go-name": "Name" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Scopes" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateBranchProtectionOption": { + "description": "CreateBranchProtectionOption options for creating a branch protection", + "type": "object", + "properties": { + "apply_to_admins": { + "type": "boolean", + "x-go-name": "ApplyToAdmins" + }, + "approvals_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistTeams" + }, + "approvals_whitelist_username": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistUsernames" + }, + "block_on_official_review_requests": { + "type": "boolean", + "x-go-name": "BlockOnOfficialReviewRequests" + }, + "block_on_outdated_branch": { + "type": "boolean", + "x-go-name": "BlockOnOutdatedBranch" + }, + "block_on_rejected_reviews": { + "type": "boolean", + "x-go-name": "BlockOnRejectedReviews" + }, + "branch_name": { + "description": "Deprecated: true", + "type": "string", + "x-go-name": "BranchName" + }, + "dismiss_stale_approvals": { + "type": "boolean", + "x-go-name": "DismissStaleApprovals" + }, + "enable_approvals_whitelist": { + "type": "boolean", + "x-go-name": "EnableApprovalsWhitelist" + }, + "enable_merge_whitelist": { + "type": "boolean", + "x-go-name": "EnableMergeWhitelist" + }, + "enable_push": { + "type": "boolean", + "x-go-name": "EnablePush" + }, + "enable_push_whitelist": { + "type": "boolean", + "x-go-name": "EnablePushWhitelist" + }, + "enable_status_check": { + "type": "boolean", + "x-go-name": "EnableStatusCheck" + }, + "ignore_stale_approvals": { + "type": "boolean", + "x-go-name": "IgnoreStaleApprovals" + }, + "merge_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistTeams" + }, + "merge_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistUsernames" + }, + "protected_file_patterns": { + "type": "string", + "x-go-name": "ProtectedFilePatterns" + }, + "push_whitelist_deploy_keys": { + "type": "boolean", + "x-go-name": "PushWhitelistDeployKeys" + }, + "push_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistTeams" + }, + "push_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistUsernames" + }, + "require_signed_commits": { + "type": "boolean", + "x-go-name": "RequireSignedCommits" + }, + "required_approvals": { + "type": "integer", + "format": "int64", + "x-go-name": "RequiredApprovals" + }, + "rule_name": { + "type": "string", + "x-go-name": "RuleName" + }, + "status_check_contexts": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "StatusCheckContexts" + }, + "unprotected_file_patterns": { + "type": "string", + "x-go-name": "UnprotectedFilePatterns" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateBranchRepoOption": { + "description": "CreateBranchRepoOption options when creating a branch in a repository", + "type": "object", + "required": ["new_branch_name"], + "properties": { + "new_branch_name": { + "description": "Name of the branch to create", + "type": "string", + "uniqueItems": true, + "x-go-name": "BranchName" + }, + "old_branch_name": { + "description": "Deprecated: true\nName of the old branch to create from", + "type": "string", + "uniqueItems": true, + "x-go-name": "OldBranchName" + }, + "old_ref_name": { + "description": "Name of the old branch/tag/commit to create from", + "type": "string", + "uniqueItems": true, + "x-go-name": "OldRefName" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateEmailOption": { + "description": "CreateEmailOption options when creating email addresses", + "type": "object", + "properties": { + "emails": { + "description": "email addresses to add", + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Emails" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateFileOptions": { + "description": "CreateFileOptions options for creating files\nNote: `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": "object", + "required": ["content"], + "properties": { + "author": { + "$ref": "#/definitions/Identity" + }, + "branch": { + "description": "branch (optional) to base this file from. if not given, the default branch is used", + "type": "string", + "x-go-name": "BranchName" + }, + "committer": { + "$ref": "#/definitions/Identity" + }, + "content": { + "description": "content must be base64 encoded", + "type": "string", + "x-go-name": "ContentBase64" + }, + "dates": { + "$ref": "#/definitions/CommitDateOptions" + }, + "message": { + "description": "message (optional) for the commit of this file. if not supplied, a default message will be used", + "type": "string", + "x-go-name": "Message" + }, + "new_branch": { + "description": "new_branch (optional) will make a new branch from `branch` before creating the file", + "type": "string", + "x-go-name": "NewBranchName" + }, + "signoff": { + "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.", + "type": "boolean", + "x-go-name": "Signoff" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateForkOption": { + "description": "CreateForkOption options for creating a fork", + "type": "object", + "properties": { + "name": { + "description": "name of the forked repository", + "type": "string", + "x-go-name": "Name" + }, + "organization": { + "description": "organization name, if forking into an organization", + "type": "string", + "x-go-name": "Organization" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateGPGKeyOption": { + "description": "CreateGPGKeyOption options create user GPG key", + "type": "object", + "required": ["armored_public_key"], + "properties": { + "armored_public_key": { + "description": "An armored GPG key to add", + "type": "string", + "uniqueItems": true, + "x-go-name": "ArmoredKey" + }, + "armored_signature": { + "type": "string", + "x-go-name": "Signature" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateHookOption": { + "description": "CreateHookOption options when create a hook", + "type": "object", + "required": ["type", "config"], + "properties": { + "active": { + "type": "boolean", + "default": false, + "x-go-name": "Active" + }, + "authorization_header": { + "type": "string", + "x-go-name": "AuthorizationHeader" + }, + "branch_filter": { + "type": "string", + "x-go-name": "BranchFilter" + }, + "config": { + "$ref": "#/definitions/CreateHookOptionConfig" + }, + "events": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Events" + }, + "type": { + "type": "string", + "enum": [ + "forgejo", + "dingtalk", + "discord", + "gitea", + "gogs", + "msteams", + "slack", + "telegram", + "feishu", + "wechatwork", + "packagist" + ], + "x-go-name": "Type" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateHookOptionConfig": { + "description": "CreateHookOptionConfig has all config options in it\nrequired are \"content_type\" and \"url\" Required", + "type": "object", + "required": ["content_type", "url"], + "additionalProperties": { + "type": "string" + }, + "properties": { + "content_type": { + "type": "string" + }, + "url": { + "type": "string", + "format": "url" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateIssueCommentOption": { + "description": "CreateIssueCommentOption options for creating a comment on an issue", + "type": "object", + "required": ["body"], + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateIssueOption": { + "description": "CreateIssueOption options to create one issue", + "type": "object", + "required": ["title"], + "properties": { + "assignee": { + "description": "deprecated", + "type": "string", + "x-go-name": "Assignee" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Assignees" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "closed": { + "type": "boolean", + "x-go-name": "Closed" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "labels": { + "description": "list of label ids", + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "x-go-name": "Labels" + }, + "milestone": { + "description": "milestone id", + "type": "integer", + "format": "int64", + "x-go-name": "Milestone" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateKeyOption": { + "description": "CreateKeyOption options when creating a key", + "type": "object", + "required": ["title", "key"], + "properties": { + "key": { + "description": "An armored SSH key to add", + "type": "string", + "uniqueItems": true, + "x-go-name": "Key" + }, + "read_only": { + "description": "Describe if the key has only read access or read/write", + "type": "boolean", + "x-go-name": "ReadOnly" + }, + "title": { + "description": "Title of the key to add", + "type": "string", + "uniqueItems": true, + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateLabelOption": { + "description": "CreateLabelOption options for creating a label", + "type": "object", + "required": ["name", "color"], + "properties": { + "color": { + "type": "string", + "x-go-name": "Color", + "example": "#00aabb" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "exclusive": { + "type": "boolean", + "x-go-name": "Exclusive", + "example": false + }, + "is_archived": { + "type": "boolean", + "x-go-name": "IsArchived", + "example": false + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateMilestoneOption": { + "description": "CreateMilestoneOption options for creating a milestone", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "due_on": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "state": { + "type": "string", + "enum": ["open", "closed"], + "x-go-name": "State" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateOAuth2ApplicationOptions": { + "description": "CreateOAuth2ApplicationOptions holds options to create an oauth2 application", + "type": "object", + "properties": { + "confidential_client": { + "type": "boolean", + "x-go-name": "ConfidentialClient" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "redirect_uris": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "RedirectURIs" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateOrUpdateSecretOption": { + "description": "CreateOrUpdateSecretOption options when creating or updating secret", + "type": "object", + "required": ["data"], + "properties": { + "data": { + "description": "Data of the secret to update", + "type": "string", + "x-go-name": "Data" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateOrgOption": { + "description": "CreateOrgOption options for creating an organization", + "type": "object", + "required": ["username"], + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "email": { + "type": "string", + "x-go-name": "Email" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "repo_admin_change_team_access": { + "type": "boolean", + "x-go-name": "RepoAdminChangeTeamAccess" + }, + "username": { + "type": "string", + "x-go-name": "UserName" + }, + "visibility": { + "description": "possible values are `public` (default), `limited` or `private`", + "type": "string", + "enum": ["public", "limited", "private"], + "x-go-name": "Visibility" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreatePullRequestOption": { + "description": "CreatePullRequestOption options when creating a pull request", + "type": "object", + "properties": { + "assignee": { + "type": "string", + "x-go-name": "Assignee" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Assignees" + }, + "base": { + "type": "string", + "x-go-name": "Base" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "head": { + "type": "string", + "x-go-name": "Head" + }, + "labels": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "x-go-name": "Labels" + }, + "milestone": { + "type": "integer", + "format": "int64", + "x-go-name": "Milestone" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreatePullReviewComment": { + "description": "CreatePullReviewComment represent a review comment for creation api", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "new_position": { + "description": "if comment to new file line or 0", + "type": "integer", + "format": "int64", + "x-go-name": "NewLineNum" + }, + "old_position": { + "description": "if comment to old file line or 0", + "type": "integer", + "format": "int64", + "x-go-name": "OldLineNum" + }, + "path": { + "description": "the tree path", + "type": "string", + "x-go-name": "Path" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreatePullReviewCommentOptions": { + "description": "CreatePullReviewCommentOptions are options to create a pull review comment", + "$ref": "#/definitions/CreatePullReviewComment" + }, + "CreatePullReviewOptions": { + "description": "CreatePullReviewOptions are options to create a pull review", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "comments": { + "type": "array", + "items": { + "$ref": "#/definitions/CreatePullReviewComment" + }, + "x-go-name": "Comments" + }, + "commit_id": { + "type": "string", + "x-go-name": "CommitID" + }, + "event": { + "$ref": "#/definitions/ReviewStateType" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreatePushMirrorOption": { + "type": "object", + "title": "CreatePushMirrorOption represents need information to create a push mirror of a repository.", + "properties": { + "interval": { + "type": "string", + "x-go-name": "Interval" + }, + "remote_address": { + "type": "string", + "x-go-name": "RemoteAddress" + }, + "remote_password": { + "type": "string", + "x-go-name": "RemotePassword" + }, + "remote_username": { + "type": "string", + "x-go-name": "RemoteUsername" + }, + "sync_on_commit": { + "type": "boolean", + "x-go-name": "SyncOnCommit" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateReleaseOption": { + "description": "CreateReleaseOption options when creating a release", + "type": "object", + "required": ["tag_name"], + "properties": { + "body": { + "type": "string", + "x-go-name": "Note" + }, + "draft": { + "type": "boolean", + "x-go-name": "IsDraft" + }, + "hide_archive_links": { + "type": "boolean", + "x-go-name": "HideArchiveLinks" + }, + "name": { + "type": "string", + "x-go-name": "Title" + }, + "prerelease": { + "type": "boolean", + "x-go-name": "IsPrerelease" + }, + "tag_name": { + "type": "string", + "x-go-name": "TagName" + }, + "target_commitish": { + "type": "string", + "x-go-name": "Target" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateRepoOption": { + "description": "CreateRepoOption options when creating repository", + "type": "object", + "required": ["name"], + "properties": { + "auto_init": { + "description": "Whether the repository should be auto-initialized?", + "type": "boolean", + "x-go-name": "AutoInit" + }, + "default_branch": { + "description": "DefaultBranch of the repository (used when initializes and in template)", + "type": "string", + "x-go-name": "DefaultBranch" + }, + "description": { + "description": "Description of the repository to create", + "type": "string", + "x-go-name": "Description" + }, + "gitignores": { + "description": "Gitignores to use", + "type": "string", + "x-go-name": "Gitignores" + }, + "issue_labels": { + "description": "Label-Set to use", + "type": "string", + "x-go-name": "IssueLabels" + }, + "license": { + "description": "License to use", + "type": "string", + "x-go-name": "License" + }, + "name": { + "description": "Name of the repository to create", + "type": "string", + "uniqueItems": true, + "x-go-name": "Name" + }, + "object_format_name": { + "$ref": "#/definitions/ObjectFormatName" + }, + "private": { + "description": "Whether the repository is private", + "type": "boolean", + "x-go-name": "Private" + }, + "readme": { + "description": "Readme of the repository to create", + "type": "string", + "x-go-name": "Readme" + }, + "template": { + "description": "Whether the repository is template", + "type": "boolean", + "x-go-name": "Template" + }, + "trust_model": { + "description": "TrustModel of the repository", + "type": "string", + "enum": [ + "default", + "collaborator", + "committer", + "collaboratorcommitter" + ], + "x-go-name": "TrustModel" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateStatusOption": { + "description": "CreateStatusOption holds the information needed to create a new CommitStatus for a Commit", + "type": "object", + "properties": { + "context": { + "type": "string", + "x-go-name": "Context" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "state": { + "$ref": "#/definitions/CommitStatusState" + }, + "target_url": { + "type": "string", + "format": "url", + "x-go-name": "TargetURL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateTagOption": { + "description": "CreateTagOption options when creating a tag", + "type": "object", + "required": ["tag_name"], + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "tag_name": { + "type": "string", + "x-go-name": "TagName" + }, + "target": { + "type": "string", + "x-go-name": "Target" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateTagProtectionOption": { + "description": "CreateTagProtectionOption options for creating a tag protection", + "type": "object", + "properties": { + "name_pattern": { + "type": "string", + "x-go-name": "NamePattern" + }, + "whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistTeams" + }, + "whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistUsernames" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateTeamOption": { + "description": "CreateTeamOption options for creating a team", + "type": "object", + "required": ["name"], + "properties": { + "can_create_org_repo": { + "type": "boolean", + "x-go-name": "CanCreateOrgRepo" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "includes_all_repositories": { + "type": "boolean", + "x-go-name": "IncludesAllRepositories" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "permission": { + "type": "string", + "enum": ["read", "write", "admin"], + "x-go-name": "Permission" + }, + "units": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Units", + "example": [ + "repo.actions", + "repo.code", + "repo.issues", + "repo.ext_issues", + "repo.wiki", + "repo.ext_wiki", + "repo.pulls", + "repo.releases", + "repo.projects", + "repo.ext_wiki" + ] + }, + "units_map": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "UnitsMap", + "example": "{\"repo.actions\",\"repo.packages\",\"repo.code\":\"read\",\"repo.issues\":\"write\",\"repo.ext_issues\":\"none\",\"repo.wiki\":\"admin\",\"repo.pulls\":\"owner\",\"repo.releases\":\"none\",\"repo.projects\":\"none\",\"repo.ext_wiki\":\"none\"}" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateUserOption": { + "description": "CreateUserOption create user options", + "type": "object", + "required": ["username", "email"], + "properties": { + "created_at": { + "description": "For explicitly setting the user creation timestamp. Useful when users are\nmigrated from other systems. When omitted, the user's creation timestamp\nwill be set to \"now\".", + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "login_name": { + "type": "string", + "x-go-name": "LoginName" + }, + "must_change_password": { + "type": "boolean", + "x-go-name": "MustChangePassword" + }, + "password": { + "type": "string", + "x-go-name": "Password" + }, + "restricted": { + "type": "boolean", + "x-go-name": "Restricted" + }, + "send_notify": { + "type": "boolean", + "x-go-name": "SendNotify" + }, + "source_id": { + "type": "integer", + "format": "int64", + "x-go-name": "SourceID" + }, + "username": { + "type": "string", + "x-go-name": "Username" + }, + "visibility": { + "type": "string", + "x-go-name": "Visibility" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateVariableOption": { + "description": "CreateVariableOption the option when creating variable", + "type": "object", + "required": ["value"], + "properties": { + "value": { + "description": "Value of the variable to create", + "type": "string", + "x-go-name": "Value" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "CreateWikiPageOptions": { + "description": "CreateWikiPageOptions form for creating wiki", + "type": "object", + "properties": { + "content_base64": { + "description": "content must be base64 encoded", + "type": "string", + "x-go-name": "ContentBase64" + }, + "message": { + "description": "optional commit message summarizing the change", + "type": "string", + "x-go-name": "Message" + }, + "title": { + "description": "page title. leave empty to keep unchanged", + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Cron": { + "description": "Cron represents a Cron task", + "type": "object", + "properties": { + "exec_times": { + "type": "integer", + "format": "int64", + "x-go-name": "ExecTimes" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "next": { + "type": "string", + "format": "date-time", + "x-go-name": "Next" + }, + "prev": { + "type": "string", + "format": "date-time", + "x-go-name": "Prev" + }, + "schedule": { + "type": "string", + "x-go-name": "Schedule" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DefaultMergeStyle": { + "type": "string", + "enum": ["merge", "rebase", "rebase-merge", "squash", "fast-forward-only"] + }, + "DeleteEmailOption": { + "description": "DeleteEmailOption options when deleting email addresses", + "type": "object", + "properties": { + "emails": { + "description": "email addresses to delete", + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Emails" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DeleteFileOptions": { + "description": "DeleteFileOptions options for deleting files (used for other File structs below)\nNote: `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": "object", + "required": ["sha"], + "properties": { + "author": { + "$ref": "#/definitions/Identity" + }, + "branch": { + "description": "branch (optional) to base this file from. if not given, the default branch is used", + "type": "string", + "x-go-name": "BranchName" + }, + "committer": { + "$ref": "#/definitions/Identity" + }, + "dates": { + "$ref": "#/definitions/CommitDateOptions" + }, + "message": { + "description": "message (optional) for the commit of this file. if not supplied, a default message will be used", + "type": "string", + "x-go-name": "Message" + }, + "new_branch": { + "description": "new_branch (optional) will make a new branch from `branch` before creating the file", + "type": "string", + "x-go-name": "NewBranchName" + }, + "sha": { + "description": "sha is the SHA for the file that already exists", + "type": "string", + "x-go-name": "SHA" + }, + "signoff": { + "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.", + "type": "boolean", + "x-go-name": "Signoff" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DeleteLabelsOption": { + "description": "DeleteLabelOption options for deleting a label", + "type": "object", + "properties": { + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DeployKey": { + "description": "DeployKey a deploy key", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "fingerprint": { + "type": "string", + "x-go-name": "Fingerprint" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "key": { + "type": "string", + "x-go-name": "Key" + }, + "key_id": { + "type": "integer", + "format": "int64", + "x-go-name": "KeyID" + }, + "read_only": { + "type": "boolean", + "x-go-name": "ReadOnly" + }, + "repository": { + "$ref": "#/definitions/Repository" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DismissPullReviewOptions": { + "description": "DismissPullReviewOptions are options to dismiss a pull review", + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "priors": { + "type": "boolean", + "x-go-name": "Priors" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "DispatchWorkflowOption": { + "description": "DispatchWorkflowOption options when dispatching a workflow", + "type": "object", + "required": ["ref"], + "properties": { + "inputs": { + "description": "Input keys and values configured in the workflow file.", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "Inputs" + }, + "ref": { + "description": "Git reference for the workflow", + "type": "string", + "x-go-name": "Ref" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditAttachmentOptions": { + "description": "EditAttachmentOptions options for editing attachments", + "type": "object", + "properties": { + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditBranchProtectionOption": { + "description": "EditBranchProtectionOption options for editing a branch protection", + "type": "object", + "properties": { + "apply_to_admins": { + "type": "boolean", + "x-go-name": "ApplyToAdmins" + }, + "approvals_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistTeams" + }, + "approvals_whitelist_username": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "ApprovalsWhitelistUsernames" + }, + "block_on_official_review_requests": { + "type": "boolean", + "x-go-name": "BlockOnOfficialReviewRequests" + }, + "block_on_outdated_branch": { + "type": "boolean", + "x-go-name": "BlockOnOutdatedBranch" + }, + "block_on_rejected_reviews": { + "type": "boolean", + "x-go-name": "BlockOnRejectedReviews" + }, + "dismiss_stale_approvals": { + "type": "boolean", + "x-go-name": "DismissStaleApprovals" + }, + "enable_approvals_whitelist": { + "type": "boolean", + "x-go-name": "EnableApprovalsWhitelist" + }, + "enable_merge_whitelist": { + "type": "boolean", + "x-go-name": "EnableMergeWhitelist" + }, + "enable_push": { + "type": "boolean", + "x-go-name": "EnablePush" + }, + "enable_push_whitelist": { + "type": "boolean", + "x-go-name": "EnablePushWhitelist" + }, + "enable_status_check": { + "type": "boolean", + "x-go-name": "EnableStatusCheck" + }, + "ignore_stale_approvals": { + "type": "boolean", + "x-go-name": "IgnoreStaleApprovals" + }, + "merge_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistTeams" + }, + "merge_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "MergeWhitelistUsernames" + }, + "protected_file_patterns": { + "type": "string", + "x-go-name": "ProtectedFilePatterns" + }, + "push_whitelist_deploy_keys": { + "type": "boolean", + "x-go-name": "PushWhitelistDeployKeys" + }, + "push_whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistTeams" + }, + "push_whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "PushWhitelistUsernames" + }, + "require_signed_commits": { + "type": "boolean", + "x-go-name": "RequireSignedCommits" + }, + "required_approvals": { + "type": "integer", + "format": "int64", + "x-go-name": "RequiredApprovals" + }, + "status_check_contexts": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "StatusCheckContexts" + }, + "unprotected_file_patterns": { + "type": "string", + "x-go-name": "UnprotectedFilePatterns" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditDeadlineOption": { + "description": "EditDeadlineOption options for creating a deadline", + "type": "object", + "required": ["due_date"], + "properties": { + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditGitHookOption": { + "description": "EditGitHookOption options when modifying one Git hook", + "type": "object", + "properties": { + "content": { + "type": "string", + "x-go-name": "Content" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditHookOption": { + "description": "EditHookOption options when modify one hook", + "type": "object", + "properties": { + "active": { + "type": "boolean", + "x-go-name": "Active" + }, + "authorization_header": { + "type": "string", + "x-go-name": "AuthorizationHeader" + }, + "branch_filter": { + "type": "string", + "x-go-name": "BranchFilter" + }, + "config": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "Config" + }, + "events": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Events" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditIssueCommentOption": { + "description": "EditIssueCommentOption options for editing a comment", + "type": "object", + "required": ["body"], + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditIssueOption": { + "description": "EditIssueOption options for editing an issue", + "type": "object", + "properties": { + "assignee": { + "description": "deprecated", + "type": "string", + "x-go-name": "Assignee" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Assignees" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "milestone": { + "type": "integer", + "format": "int64", + "x-go-name": "Milestone" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "state": { + "type": "string", + "x-go-name": "State" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "unset_due_date": { + "type": "boolean", + "x-go-name": "RemoveDeadline" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditLabelOption": { + "description": "EditLabelOption options for editing a label", + "type": "object", + "properties": { + "color": { + "type": "string", + "x-go-name": "Color", + "example": "#00aabb" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "exclusive": { + "type": "boolean", + "x-go-name": "Exclusive", + "example": false + }, + "is_archived": { + "type": "boolean", + "x-go-name": "IsArchived", + "example": false + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditMilestoneOption": { + "description": "EditMilestoneOption options for editing a milestone", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "due_on": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "state": { + "type": "string", + "x-go-name": "State" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditOrgOption": { + "description": "EditOrgOption options for editing an organization", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "email": { + "type": "string", + "x-go-name": "Email" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "repo_admin_change_team_access": { + "type": "boolean", + "x-go-name": "RepoAdminChangeTeamAccess" + }, + "visibility": { + "description": "possible values are `public`, `limited` or `private`", + "type": "string", + "enum": ["public", "limited", "private"], + "x-go-name": "Visibility" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditPullRequestOption": { + "description": "EditPullRequestOption options when modify pull request", + "type": "object", + "properties": { + "allow_maintainer_edit": { + "type": "boolean", + "x-go-name": "AllowMaintainerEdit" + }, + "assignee": { + "type": "string", + "x-go-name": "Assignee" + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Assignees" + }, + "base": { + "type": "string", + "x-go-name": "Base" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "labels": { + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "x-go-name": "Labels" + }, + "milestone": { + "type": "integer", + "format": "int64", + "x-go-name": "Milestone" + }, + "state": { + "type": "string", + "x-go-name": "State" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "unset_due_date": { + "type": "boolean", + "x-go-name": "RemoveDeadline" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditReactionOption": { + "description": "EditReactionOption contain the reaction type", + "type": "object", + "properties": { + "content": { + "type": "string", + "x-go-name": "Reaction" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditReleaseOption": { + "description": "EditReleaseOption options when editing a release", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Note" + }, + "draft": { + "type": "boolean", + "x-go-name": "IsDraft" + }, + "hide_archive_links": { + "type": "boolean", + "x-go-name": "HideArchiveLinks" + }, + "name": { + "type": "string", + "x-go-name": "Title" + }, + "prerelease": { + "type": "boolean", + "x-go-name": "IsPrerelease" + }, + "tag_name": { + "type": "string", + "x-go-name": "TagName" + }, + "target_commitish": { + "type": "string", + "x-go-name": "Target" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditRepoOption": { + "description": "EditRepoOption options when editing a repository's properties", + "type": "object", + "properties": { + "allow_fast_forward_only_merge": { + "description": "either `true` to allow fast-forward-only merging pull requests, or `false` to prevent fast-forward-only merging.", + "type": "boolean", + "x-go-name": "AllowFastForwardOnly" + }, + "allow_manual_merge": { + "description": "either `true` to allow mark pr as merged manually, or `false` to prevent it.", + "type": "boolean", + "x-go-name": "AllowManualMerge" + }, + "allow_merge_commits": { + "description": "either `true` to allow merging pull requests with a merge commit, or `false` to prevent merging pull requests with merge commits.", + "type": "boolean", + "x-go-name": "AllowMerge" + }, + "allow_rebase": { + "description": "either `true` to allow rebase-merging pull requests, or `false` to prevent rebase-merging.", + "type": "boolean", + "x-go-name": "AllowRebase" + }, + "allow_rebase_explicit": { + "description": "either `true` to allow rebase with explicit merge commits (--no-ff), or `false` to prevent rebase with explicit merge commits.", + "type": "boolean", + "x-go-name": "AllowRebaseMerge" + }, + "allow_rebase_update": { + "description": "either `true` to allow updating pull request branch by rebase, or `false` to prevent it.", + "type": "boolean", + "x-go-name": "AllowRebaseUpdate" + }, + "allow_squash_merge": { + "description": "either `true` to allow squash-merging pull requests, or `false` to prevent squash-merging.", + "type": "boolean", + "x-go-name": "AllowSquash" + }, + "archived": { + "description": "set to `true` to archive this repository.", + "type": "boolean", + "x-go-name": "Archived" + }, + "autodetect_manual_merge": { + "description": "either `true` to enable AutodetectManualMerge, or `false` to prevent it. Note: In some special cases, misjudgments can occur.", + "type": "boolean", + "x-go-name": "AutodetectManualMerge" + }, + "default_allow_maintainer_edit": { + "description": "set to `true` to allow edits from maintainers by default", + "type": "boolean", + "x-go-name": "DefaultAllowMaintainerEdit" + }, + "default_branch": { + "description": "sets the default branch for this repository.", + "type": "string", + "x-go-name": "DefaultBranch" + }, + "default_delete_branch_after_merge": { + "description": "set to `true` to delete pr branch after merge by default", + "type": "boolean", + "x-go-name": "DefaultDeleteBranchAfterMerge" + }, + "default_merge_style": { + "$ref": "#/definitions/DefaultMergeStyle" + }, + "description": { + "description": "a short description of the repository.", + "type": "string", + "x-go-name": "Description" + }, + "enable_prune": { + "description": "enable prune - remove obsolete remote-tracking references when mirroring", + "type": "boolean", + "x-go-name": "EnablePrune" + }, + "external_tracker": { + "$ref": "#/definitions/ExternalTracker" + }, + "external_wiki": { + "$ref": "#/definitions/ExternalWiki" + }, + "globally_editable_wiki": { + "description": "set the globally editable state of the wiki", + "type": "boolean", + "x-go-name": "GloballyEditableWiki" + }, + "has_actions": { + "description": "either `true` to enable actions unit, or `false` to disable them.", + "type": "boolean", + "x-go-name": "HasActions" + }, + "has_issues": { + "description": "either `true` to enable issues for this repository or `false` to disable them.", + "type": "boolean", + "x-go-name": "HasIssues" + }, + "has_packages": { + "description": "either `true` to enable packages unit, or `false` to disable them.", + "type": "boolean", + "x-go-name": "HasPackages" + }, + "has_projects": { + "description": "either `true` to enable project unit, or `false` to disable them.", + "type": "boolean", + "x-go-name": "HasProjects" + }, + "has_pull_requests": { + "description": "either `true` to allow pull requests, or `false` to prevent pull request.", + "type": "boolean", + "x-go-name": "HasPullRequests" + }, + "has_releases": { + "description": "either `true` to enable releases unit, or `false` to disable them.", + "type": "boolean", + "x-go-name": "HasReleases" + }, + "has_wiki": { + "description": "either `true` to enable the wiki for this repository or `false` to disable it.", + "type": "boolean", + "x-go-name": "HasWiki" + }, + "ignore_whitespace_conflicts": { + "description": "either `true` to ignore whitespace for conflicts, or `false` to not ignore whitespace.", + "type": "boolean", + "x-go-name": "IgnoreWhitespaceConflicts" + }, + "internal_tracker": { + "$ref": "#/definitions/InternalTracker" + }, + "mirror_interval": { + "description": "set to a string like `8h30m0s` to set the mirror interval time", + "type": "string", + "x-go-name": "MirrorInterval" + }, + "name": { + "description": "name of the repository", + "type": "string", + "uniqueItems": true, + "x-go-name": "Name" + }, + "private": { + "description": "either `true` to make the repository private or `false` to make it public.\nNote: you will get a 422 error if the organization restricts changing repository visibility to organization\nowners and a non-owner tries to change the value of private.", + "type": "boolean", + "x-go-name": "Private" + }, + "template": { + "description": "either `true` to make this repository a template or `false` to make it a normal repository", + "type": "boolean", + "x-go-name": "Template" + }, + "website": { + "description": "a URL with more information about the repository.", + "type": "string", + "x-go-name": "Website" + }, + "wiki_branch": { + "description": "sets the branch used for this repository's wiki.", + "type": "string", + "x-go-name": "WikiBranch" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditTagProtectionOption": { + "description": "EditTagProtectionOption options for editing a tag protection", + "type": "object", + "properties": { + "name_pattern": { + "type": "string", + "x-go-name": "NamePattern" + }, + "whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistTeams" + }, + "whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistUsernames" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditTeamOption": { + "description": "EditTeamOption options for editing a team", + "type": "object", + "required": ["name"], + "properties": { + "can_create_org_repo": { + "type": "boolean", + "x-go-name": "CanCreateOrgRepo" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "includes_all_repositories": { + "type": "boolean", + "x-go-name": "IncludesAllRepositories" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "permission": { + "type": "string", + "enum": ["read", "write", "admin"], + "x-go-name": "Permission" + }, + "units": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Units", + "example": [ + "repo.code", + "repo.issues", + "repo.ext_issues", + "repo.wiki", + "repo.pulls", + "repo.releases", + "repo.projects", + "repo.ext_wiki" + ] + }, + "units_map": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "UnitsMap", + "example": { + "repo.code": "read", + "repo.ext_issues": "none", + "repo.ext_wiki": "none", + "repo.issues": "write", + "repo.projects": "none", + "repo.pulls": "owner", + "repo.releases": "none", + "repo.wiki": "admin" + } + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "EditUserOption": { + "description": "EditUserOption edit user options", + "type": "object", + "properties": { + "active": { + "type": "boolean", + "x-go-name": "Active" + }, + "admin": { + "type": "boolean", + "x-go-name": "Admin" + }, + "allow_create_organization": { + "type": "boolean", + "x-go-name": "AllowCreateOrganization" + }, + "allow_git_hook": { + "type": "boolean", + "x-go-name": "AllowGitHook" + }, + "allow_import_local": { + "type": "boolean", + "x-go-name": "AllowImportLocal" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "login_name": { + "type": "string", + "x-go-name": "LoginName" + }, + "max_repo_creation": { + "type": "integer", + "format": "int64", + "x-go-name": "MaxRepoCreation" + }, + "must_change_password": { + "type": "boolean", + "x-go-name": "MustChangePassword" + }, + "password": { + "type": "string", + "x-go-name": "Password" + }, + "prohibit_login": { + "type": "boolean", + "x-go-name": "ProhibitLogin" + }, + "pronouns": { + "type": "string", + "x-go-name": "Pronouns" + }, + "restricted": { + "type": "boolean", + "x-go-name": "Restricted" + }, + "source_id": { + "type": "integer", + "format": "int64", + "x-go-name": "SourceID" + }, + "visibility": { + "type": "string", + "x-go-name": "Visibility" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Email": { + "description": "Email an email address belonging to a user", + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "primary": { + "type": "boolean", + "x-go-name": "Primary" + }, + "user_id": { + "type": "integer", + "format": "int64", + "x-go-name": "UserID" + }, + "username": { + "type": "string", + "x-go-name": "UserName" + }, + "verified": { + "type": "boolean", + "x-go-name": "Verified" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ExternalTracker": { + "description": "ExternalTracker represents settings for external tracker", + "type": "object", + "properties": { + "external_tracker_format": { + "description": "External Issue Tracker URL Format. Use the placeholders {user}, {repo} and {index} for the username, repository name and issue index.", + "type": "string", + "x-go-name": "ExternalTrackerFormat" + }, + "external_tracker_regexp_pattern": { + "description": "External Issue Tracker issue regular expression", + "type": "string", + "x-go-name": "ExternalTrackerRegexpPattern" + }, + "external_tracker_style": { + "description": "External Issue Tracker Number Format, either `numeric`, `alphanumeric`, or `regexp`", + "type": "string", + "x-go-name": "ExternalTrackerStyle" + }, + "external_tracker_url": { + "description": "URL of external issue tracker.", + "type": "string", + "format": "url", + "x-go-name": "ExternalTrackerURL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ExternalWiki": { + "description": "ExternalWiki represents setting for external wiki", + "type": "object", + "properties": { + "external_wiki_url": { + "description": "URL of external wiki.", + "type": "string", + "format": "url", + "x-go-name": "ExternalWikiURL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "FileCommitResponse": { + "type": "object", + "title": "FileCommitResponse contains information generated from a Git commit for a repo's file.", + "properties": { + "author": { + "$ref": "#/definitions/CommitUser" + }, + "committer": { + "$ref": "#/definitions/CommitUser" + }, + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "parents": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitMeta" + }, + "x-go-name": "Parents" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "tree": { + "$ref": "#/definitions/CommitMeta" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "FileDeleteResponse": { + "description": "FileDeleteResponse contains information about a repo's file that was deleted", + "type": "object", + "properties": { + "commit": { + "$ref": "#/definitions/FileCommitResponse" + }, + "content": { + "x-go-name": "Content" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "FileLinksResponse": { + "description": "FileLinksResponse contains the links for a repo's file", + "type": "object", + "properties": { + "git": { + "type": "string", + "x-go-name": "GitURL" + }, + "html": { + "type": "string", + "x-go-name": "HTMLURL" + }, + "self": { + "type": "string", + "x-go-name": "Self" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "FileResponse": { + "description": "FileResponse contains information about a repo's file", + "type": "object", + "properties": { + "commit": { + "$ref": "#/definitions/FileCommitResponse" + }, + "content": { + "$ref": "#/definitions/ContentsResponse" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "FilesResponse": { + "description": "FilesResponse contains information about multiple files from a repo", + "type": "object", + "properties": { + "commit": { + "$ref": "#/definitions/FileCommitResponse" + }, + "files": { + "type": "array", + "items": { + "$ref": "#/definitions/ContentsResponse" + }, + "x-go-name": "Files" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ForgeLike": { + "description": "ForgeLike activity data type", + "type": "object", + "x-go-package": "code.gitea.io/gitea/modules/forgefed" + }, + "GPGKey": { + "description": "GPGKey a user GPG key to sign commit and tag in repository", + "type": "object", + "properties": { + "can_certify": { + "type": "boolean", + "x-go-name": "CanCertify" + }, + "can_encrypt_comms": { + "type": "boolean", + "x-go-name": "CanEncryptComms" + }, + "can_encrypt_storage": { + "type": "boolean", + "x-go-name": "CanEncryptStorage" + }, + "can_sign": { + "type": "boolean", + "x-go-name": "CanSign" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "emails": { + "type": "array", + "items": { + "$ref": "#/definitions/GPGKeyEmail" + }, + "x-go-name": "Emails" + }, + "expires_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Expires" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "key_id": { + "type": "string", + "x-go-name": "KeyID" + }, + "primary_key_id": { + "type": "string", + "x-go-name": "PrimaryKeyID" + }, + "public_key": { + "type": "string", + "x-go-name": "PublicKey" + }, + "subkeys": { + "type": "array", + "items": { + "$ref": "#/definitions/GPGKey" + }, + "x-go-name": "SubsKey" + }, + "verified": { + "type": "boolean", + "x-go-name": "Verified" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GPGKeyEmail": { + "description": "GPGKeyEmail an email attached to a GPGKey", + "type": "object", + "properties": { + "email": { + "type": "string", + "x-go-name": "Email" + }, + "verified": { + "type": "boolean", + "x-go-name": "Verified" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GeneralAPISettings": { + "description": "GeneralAPISettings contains global api settings exposed by it", + "type": "object", + "properties": { + "default_git_trees_per_page": { + "type": "integer", + "format": "int64", + "x-go-name": "DefaultGitTreesPerPage" + }, + "default_max_blob_size": { + "type": "integer", + "format": "int64", + "x-go-name": "DefaultMaxBlobSize" + }, + "default_paging_num": { + "type": "integer", + "format": "int64", + "x-go-name": "DefaultPagingNum" + }, + "max_response_items": { + "type": "integer", + "format": "int64", + "x-go-name": "MaxResponseItems" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GeneralAttachmentSettings": { + "description": "GeneralAttachmentSettings contains global Attachment settings exposed by API", + "type": "object", + "properties": { + "allowed_types": { + "type": "string", + "x-go-name": "AllowedTypes" + }, + "enabled": { + "type": "boolean", + "x-go-name": "Enabled" + }, + "max_files": { + "type": "integer", + "format": "int64", + "x-go-name": "MaxFiles" + }, + "max_size": { + "type": "integer", + "format": "int64", + "x-go-name": "MaxSize" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GeneralRepoSettings": { + "description": "GeneralRepoSettings contains global repository settings exposed by API", + "type": "object", + "properties": { + "forks_disabled": { + "type": "boolean", + "x-go-name": "ForksDisabled" + }, + "http_git_disabled": { + "type": "boolean", + "x-go-name": "HTTPGitDisabled" + }, + "lfs_disabled": { + "type": "boolean", + "x-go-name": "LFSDisabled" + }, + "migrations_disabled": { + "type": "boolean", + "x-go-name": "MigrationsDisabled" + }, + "mirrors_disabled": { + "type": "boolean", + "x-go-name": "MirrorsDisabled" + }, + "stars_disabled": { + "type": "boolean", + "x-go-name": "StarsDisabled" + }, + "time_tracking_disabled": { + "type": "boolean", + "x-go-name": "TimeTrackingDisabled" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GeneralUISettings": { + "description": "GeneralUISettings contains global ui settings exposed by API", + "type": "object", + "properties": { + "allowed_reactions": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "AllowedReactions" + }, + "custom_emojis": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "CustomEmojis" + }, + "default_theme": { + "type": "string", + "x-go-name": "DefaultTheme" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GenerateRepoOption": { + "description": "GenerateRepoOption options when creating repository using a template", + "type": "object", + "required": ["owner", "name"], + "properties": { + "avatar": { + "description": "include avatar of the template repo", + "type": "boolean", + "x-go-name": "Avatar" + }, + "default_branch": { + "description": "Default branch of the new repository", + "type": "string", + "x-go-name": "DefaultBranch" + }, + "description": { + "description": "Description of the repository to create", + "type": "string", + "x-go-name": "Description" + }, + "git_content": { + "description": "include git content of default branch in template repo", + "type": "boolean", + "x-go-name": "GitContent" + }, + "git_hooks": { + "description": "include git hooks in template repo", + "type": "boolean", + "x-go-name": "GitHooks" + }, + "labels": { + "description": "include labels in template repo", + "type": "boolean", + "x-go-name": "Labels" + }, + "name": { + "description": "Name of the repository to create", + "type": "string", + "uniqueItems": true, + "x-go-name": "Name" + }, + "owner": { + "description": "The organization or person who will own the new repository", + "type": "string", + "x-go-name": "Owner" + }, + "private": { + "description": "Whether the repository is private", + "type": "boolean", + "x-go-name": "Private" + }, + "protected_branch": { + "description": "include protected branches in template repo", + "type": "boolean", + "x-go-name": "ProtectedBranch" + }, + "topics": { + "description": "include topics in template repo", + "type": "boolean", + "x-go-name": "Topics" + }, + "webhooks": { + "description": "include webhooks in template repo", + "type": "boolean", + "x-go-name": "Webhooks" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitBlobResponse": { + "description": "GitBlobResponse represents a git blob", + "type": "object", + "properties": { + "content": { + "type": "string", + "x-go-name": "Content" + }, + "encoding": { + "type": "string", + "x-go-name": "Encoding" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "size": { + "type": "integer", + "format": "int64", + "x-go-name": "Size" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitEntry": { + "description": "GitEntry represents a git tree", + "type": "object", + "properties": { + "mode": { + "type": "string", + "x-go-name": "Mode" + }, + "path": { + "type": "string", + "x-go-name": "Path" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "size": { + "type": "integer", + "format": "int64", + "x-go-name": "Size" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitHook": { + "description": "GitHook represents a Git repository hook", + "type": "object", + "properties": { + "content": { + "type": "string", + "x-go-name": "Content" + }, + "is_active": { + "type": "boolean", + "x-go-name": "IsActive" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitObject": { + "type": "object", + "title": "GitObject represents a Git object.", + "properties": { + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitTreeResponse": { + "description": "GitTreeResponse returns a git tree", + "type": "object", + "properties": { + "page": { + "type": "integer", + "format": "int64", + "x-go-name": "Page" + }, + "sha": { + "type": "string", + "x-go-name": "SHA" + }, + "total_count": { + "type": "integer", + "format": "int64", + "x-go-name": "TotalCount" + }, + "tree": { + "type": "array", + "items": { + "$ref": "#/definitions/GitEntry" + }, + "x-go-name": "Entries" + }, + "truncated": { + "type": "boolean", + "x-go-name": "Truncated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "GitignoreTemplateInfo": { + "description": "GitignoreTemplateInfo name and text of a gitignore template", + "type": "object", + "properties": { + "name": { + "type": "string", + "x-go-name": "Name" + }, + "source": { + "type": "string", + "x-go-name": "Source" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Hook": { + "description": "Hook a hook is a web hook when one repository changed", + "type": "object", + "properties": { + "active": { + "type": "boolean", + "x-go-name": "Active" + }, + "authorization_header": { + "type": "string", + "x-go-name": "AuthorizationHeader" + }, + "branch_filter": { + "type": "string", + "x-go-name": "BranchFilter" + }, + "config": { + "description": "Deprecated: use Metadata instead", + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "Config" + }, + "content_type": { + "type": "string", + "x-go-name": "ContentType" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "events": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Events" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "metadata": { + "x-go-name": "Metadata" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Identity": { + "description": "Identity for a person's identity like an author or committer", + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "InternalTracker": { + "description": "InternalTracker represents settings for internal tracker", + "type": "object", + "properties": { + "allow_only_contributors_to_track_time": { + "description": "Let only contributors track time (Built-in issue tracker)", + "type": "boolean", + "x-go-name": "AllowOnlyContributorsToTrackTime" + }, + "enable_issue_dependencies": { + "description": "Enable dependencies for issues and pull requests (Built-in issue tracker)", + "type": "boolean", + "x-go-name": "EnableIssueDependencies" + }, + "enable_time_tracker": { + "description": "Enable time tracking (Built-in issue tracker)", + "type": "boolean", + "x-go-name": "EnableTimeTracker" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Issue": { + "description": "Issue represents an issue in a repository", + "type": "object", + "properties": { + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/Attachment" + }, + "x-go-name": "Attachments" + }, + "assignee": { + "$ref": "#/definitions/User" + }, + "assignees": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + }, + "x-go-name": "Assignees" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "closed_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Closed" + }, + "comments": { + "type": "integer", + "format": "int64", + "x-go-name": "Comments" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "is_locked": { + "type": "boolean", + "x-go-name": "IsLocked" + }, + "labels": { + "type": "array", + "items": { + "$ref": "#/definitions/Label" + }, + "x-go-name": "Labels" + }, + "milestone": { + "$ref": "#/definitions/Milestone" + }, + "number": { + "type": "integer", + "format": "int64", + "x-go-name": "Index" + }, + "original_author": { + "type": "string", + "x-go-name": "OriginalAuthor" + }, + "original_author_id": { + "type": "integer", + "format": "int64", + "x-go-name": "OriginalAuthorID" + }, + "pin_order": { + "type": "integer", + "format": "int64", + "x-go-name": "PinOrder" + }, + "pull_request": { + "$ref": "#/definitions/PullRequestMeta" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "repository": { + "$ref": "#/definitions/RepositoryMeta" + }, + "state": { + "$ref": "#/definitions/StateType" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueConfig": { + "type": "object", + "properties": { + "blank_issues_enabled": { + "type": "boolean", + "x-go-name": "BlankIssuesEnabled" + }, + "contact_links": { + "type": "array", + "items": { + "$ref": "#/definitions/IssueConfigContactLink" + }, + "x-go-name": "ContactLinks" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueConfigContactLink": { + "type": "object", + "properties": { + "about": { + "type": "string", + "x-go-name": "About" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueConfigValidation": { + "type": "object", + "properties": { + "message": { + "type": "string", + "x-go-name": "Message" + }, + "valid": { + "type": "boolean", + "x-go-name": "Valid" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueDeadline": { + "description": "IssueDeadline represents an issue deadline", + "type": "object", + "properties": { + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueFormField": { + "description": "IssueFormField represents a form field", + "type": "object", + "properties": { + "attributes": { + "type": "object", + "additionalProperties": {}, + "x-go-name": "Attributes" + }, + "id": { + "type": "string", + "x-go-name": "ID" + }, + "type": { + "$ref": "#/definitions/IssueFormFieldType" + }, + "validations": { + "type": "object", + "additionalProperties": {}, + "x-go-name": "Validations" + }, + "visible": { + "type": "array", + "items": { + "$ref": "#/definitions/IssueFormFieldVisible" + }, + "x-go-name": "Visible" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueFormFieldType": { + "type": "string", + "title": "IssueFormFieldType defines issue form field type, can be \"markdown\", \"textarea\", \"input\", \"dropdown\" or \"checkboxes\"", + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueFormFieldVisible": { + "description": "IssueFormFieldVisible defines issue form field visible", + "type": "string", + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueLabelsOption": { + "description": "IssueLabelsOption a collection of labels", + "type": "object", + "properties": { + "labels": { + "description": "Labels can be a list of integers representing label IDs\nor a list of strings representing label names", + "type": "array", + "items": {}, + "x-go-name": "Labels" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueMeta": { + "description": "IssueMeta basic issue information", + "type": "object", + "properties": { + "index": { + "type": "integer", + "format": "int64", + "x-go-name": "Index" + }, + "owner": { + "type": "string", + "x-go-name": "Owner" + }, + "repo": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueTemplate": { + "description": "IssueTemplate represents an issue template for a repository", + "type": "object", + "properties": { + "about": { + "type": "string", + "x-go-name": "About" + }, + "body": { + "type": "array", + "items": { + "$ref": "#/definitions/IssueFormField" + }, + "x-go-name": "Fields" + }, + "content": { + "type": "string", + "x-go-name": "Content" + }, + "file_name": { + "type": "string", + "x-go-name": "FileName" + }, + "labels": { + "$ref": "#/definitions/IssueTemplateLabels" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "IssueTemplateLabels": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Label": { + "description": "Label a label to an issue or a pr", + "type": "object", + "properties": { + "color": { + "type": "string", + "x-go-name": "Color", + "example": "00aabb" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "exclusive": { + "type": "boolean", + "x-go-name": "Exclusive", + "example": false + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "is_archived": { + "type": "boolean", + "x-go-name": "IsArchived", + "example": false + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "LabelTemplate": { + "description": "LabelTemplate info of a Label template", + "type": "object", + "properties": { + "color": { + "type": "string", + "x-go-name": "Color", + "example": "00aabb" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "exclusive": { + "type": "boolean", + "x-go-name": "Exclusive", + "example": false + }, + "name": { + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "LicenseTemplateInfo": { + "description": "LicensesInfo contains information about a License", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "implementation": { + "type": "string", + "x-go-name": "Implementation" + }, + "key": { + "type": "string", + "x-go-name": "Key" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "LicensesTemplateListEntry": { + "description": "LicensesListEntry is used for the API", + "type": "object", + "properties": { + "key": { + "type": "string", + "x-go-name": "Key" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "MarkdownOption": { + "description": "MarkdownOption markdown options", + "type": "object", + "properties": { + "Context": { + "description": "Context to render\n\nin: body", + "type": "string" + }, + "Mode": { + "description": "Mode to render (comment, gfm, markdown)\n\nin: body", + "type": "string" + }, + "Text": { + "description": "Text markdown to render\n\nin: body", + "type": "string" + }, + "Wiki": { + "description": "Is it a wiki page ?\n\nin: body", + "type": "boolean" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "MarkupOption": { + "description": "MarkupOption markup options", + "type": "object", + "properties": { + "Context": { + "description": "Context to render\n\nin: body", + "type": "string" + }, + "FilePath": { + "description": "File path for detecting extension in file mode\n\nin: body", + "type": "string" + }, + "Mode": { + "description": "Mode to render (comment, gfm, markdown, file)\n\nin: body", + "type": "string" + }, + "Text": { + "description": "Text markup to render\n\nin: body", + "type": "string" + }, + "Wiki": { + "description": "Is it a wiki page ?\n\nin: body", + "type": "boolean" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "MergePullRequestOption": { + "description": "MergePullRequestForm form for merging Pull Request", + "type": "object", + "required": ["Do"], + "properties": { + "Do": { + "type": "string", + "enum": [ + "merge", + "rebase", + "rebase-merge", + "squash", + "fast-forward-only", + "manually-merged" + ] + }, + "MergeCommitID": { + "type": "string" + }, + "MergeMessageField": { + "type": "string" + }, + "MergeTitleField": { + "type": "string" + }, + "delete_branch_after_merge": { + "type": "boolean", + "x-go-name": "DeleteBranchAfterMerge" + }, + "force_merge": { + "type": "boolean", + "x-go-name": "ForceMerge" + }, + "head_commit_id": { + "type": "string", + "x-go-name": "HeadCommitID" + }, + "merge_when_checks_succeed": { + "type": "boolean", + "x-go-name": "MergeWhenChecksSucceed" + } + }, + "x-go-name": "MergePullRequestForm", + "x-go-package": "code.gitea.io/gitea/services/forms" + }, + "MigrateRepoOptions": { + "description": "MigrateRepoOptions options for migrating repository's\nthis is used to interact with api v1", + "type": "object", + "required": ["clone_addr", "repo_name"], + "properties": { + "auth_password": { + "type": "string", + "x-go-name": "AuthPassword" + }, + "auth_token": { + "type": "string", + "x-go-name": "AuthToken" + }, + "auth_username": { + "type": "string", + "x-go-name": "AuthUsername" + }, + "clone_addr": { + "type": "string", + "x-go-name": "CloneAddr" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "issues": { + "type": "boolean", + "x-go-name": "Issues" + }, + "labels": { + "type": "boolean", + "x-go-name": "Labels" + }, + "lfs": { + "type": "boolean", + "x-go-name": "LFS" + }, + "lfs_endpoint": { + "type": "string", + "x-go-name": "LFSEndpoint" + }, + "milestones": { + "type": "boolean", + "x-go-name": "Milestones" + }, + "mirror": { + "type": "boolean", + "x-go-name": "Mirror" + }, + "mirror_interval": { + "type": "string", + "x-go-name": "MirrorInterval" + }, + "private": { + "type": "boolean", + "x-go-name": "Private" + }, + "pull_requests": { + "type": "boolean", + "x-go-name": "PullRequests" + }, + "releases": { + "type": "boolean", + "x-go-name": "Releases" + }, + "repo_name": { + "type": "string", + "x-go-name": "RepoName" + }, + "repo_owner": { + "description": "Name of User or Organisation who will own Repo after migration", + "type": "string", + "x-go-name": "RepoOwner" + }, + "service": { + "type": "string", + "enum": [ + "git", + "github", + "gitea", + "gitlab", + "gogs", + "onedev", + "gitbucket", + "codebase" + ], + "x-go-name": "Service" + }, + "uid": { + "description": "deprecated (only for backwards compatibility)", + "type": "integer", + "format": "int64", + "x-go-name": "RepoOwnerID" + }, + "wiki": { + "type": "boolean", + "x-go-name": "Wiki" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Milestone": { + "description": "Milestone milestone is a collection of issues on one repository", + "type": "object", + "properties": { + "closed_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Closed" + }, + "closed_issues": { + "type": "integer", + "format": "int64", + "x-go-name": "ClosedIssues" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "due_on": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "open_issues": { + "type": "integer", + "format": "int64", + "x-go-name": "OpenIssues" + }, + "state": { + "$ref": "#/definitions/StateType" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NewIssuePinsAllowed": { + "description": "NewIssuePinsAllowed represents an API response that says if new Issue Pins are allowed", + "type": "object", + "properties": { + "issues": { + "type": "boolean", + "x-go-name": "Issues" + }, + "pull_requests": { + "type": "boolean", + "x-go-name": "PullRequests" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NodeInfo": { + "description": "NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks", + "type": "object", + "properties": { + "metadata": { + "type": "object", + "x-go-name": "Metadata" + }, + "openRegistrations": { + "type": "boolean", + "x-go-name": "OpenRegistrations" + }, + "protocols": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Protocols" + }, + "services": { + "$ref": "#/definitions/NodeInfoServices" + }, + "software": { + "$ref": "#/definitions/NodeInfoSoftware" + }, + "usage": { + "$ref": "#/definitions/NodeInfoUsage" + }, + "version": { + "type": "string", + "x-go-name": "Version" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NodeInfoServices": { + "description": "NodeInfoServices contains the third party sites this server can connect to via their application API", + "type": "object", + "properties": { + "inbound": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Inbound" + }, + "outbound": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Outbound" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NodeInfoSoftware": { + "description": "NodeInfoSoftware contains Metadata about server software in use", + "type": "object", + "properties": { + "homepage": { + "type": "string", + "x-go-name": "Homepage" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "repository": { + "type": "string", + "x-go-name": "Repository" + }, + "version": { + "type": "string", + "x-go-name": "Version" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NodeInfoUsage": { + "description": "NodeInfoUsage contains usage statistics for this server", + "type": "object", + "properties": { + "localComments": { + "type": "integer", + "format": "int64", + "x-go-name": "LocalComments" + }, + "localPosts": { + "type": "integer", + "format": "int64", + "x-go-name": "LocalPosts" + }, + "users": { + "$ref": "#/definitions/NodeInfoUsageUsers" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NodeInfoUsageUsers": { + "description": "NodeInfoUsageUsers contains statistics about the users of this server", + "type": "object", + "properties": { + "activeHalfyear": { + "type": "integer", + "format": "int64", + "x-go-name": "ActiveHalfyear" + }, + "activeMonth": { + "type": "integer", + "format": "int64", + "x-go-name": "ActiveMonth" + }, + "total": { + "type": "integer", + "format": "int64", + "x-go-name": "Total" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Note": { + "description": "Note contains information related to a git note", + "type": "object", + "properties": { + "commit": { + "$ref": "#/definitions/Commit" + }, + "message": { + "type": "string", + "x-go-name": "Message" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NotificationCount": { + "description": "NotificationCount number of unread notifications", + "type": "object", + "properties": { + "new": { + "type": "integer", + "format": "int64", + "x-go-name": "New" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NotificationSubject": { + "description": "NotificationSubject contains the notification subject (Issue/Pull/Commit)", + "type": "object", + "properties": { + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "latest_comment_html_url": { + "type": "string", + "format": "url", + "x-go-name": "LatestCommentHTMLURL" + }, + "latest_comment_url": { + "type": "string", + "format": "url", + "x-go-name": "LatestCommentURL" + }, + "state": { + "$ref": "#/definitions/StateType" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "type": { + "$ref": "#/definitions/NotifySubjectType" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NotificationThread": { + "description": "NotificationThread expose Notification on API", + "type": "object", + "properties": { + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "pinned": { + "type": "boolean", + "x-go-name": "Pinned" + }, + "repository": { + "$ref": "#/definitions/Repository" + }, + "subject": { + "$ref": "#/definitions/NotificationSubject" + }, + "unread": { + "type": "boolean", + "x-go-name": "Unread" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "UpdatedAt" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "NotifySubjectType": { + "description": "NotifySubjectType represent type of notification subject", + "type": "string", + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "OAuth2Application": { + "type": "object", + "title": "OAuth2Application represents an OAuth2 application.", + "properties": { + "client_id": { + "type": "string", + "x-go-name": "ClientID" + }, + "client_secret": { + "type": "string", + "x-go-name": "ClientSecret" + }, + "confidential_client": { + "type": "boolean", + "x-go-name": "ConfidentialClient" + }, + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "redirect_uris": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "RedirectURIs" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ObjectFormatName": { + "description": "ObjectFormatName of the underlying git repository", + "type": "string", + "enum": ["sha1", "sha256"] + }, + "Organization": { + "description": "Organization represents an organization", + "type": "object", + "properties": { + "avatar_url": { + "type": "string", + "format": "url", + "x-go-name": "AvatarURL" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "email": { + "type": "string", + "x-go-name": "Email" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "repo_admin_change_team_access": { + "type": "boolean", + "x-go-name": "RepoAdminChangeTeamAccess" + }, + "username": { + "description": "deprecated", + "type": "string", + "x-go-name": "UserName" + }, + "visibility": { + "type": "string", + "x-go-name": "Visibility" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "OrganizationPermissions": { + "description": "OrganizationPermissions list different users permissions on an organization", + "type": "object", + "properties": { + "can_create_repository": { + "type": "boolean", + "x-go-name": "CanCreateRepository" + }, + "can_read": { + "type": "boolean", + "x-go-name": "CanRead" + }, + "can_write": { + "type": "boolean", + "x-go-name": "CanWrite" + }, + "is_admin": { + "type": "boolean", + "x-go-name": "IsAdmin" + }, + "is_owner": { + "type": "boolean", + "x-go-name": "IsOwner" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PRBranchInfo": { + "description": "PRBranchInfo information about a branch", + "type": "object", + "properties": { + "label": { + "type": "string", + "x-go-name": "Name" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "repo": { + "$ref": "#/definitions/Repository" + }, + "repo_id": { + "type": "integer", + "format": "int64", + "x-go-name": "RepoID" + }, + "sha": { + "type": "string", + "x-go-name": "Sha" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Package": { + "description": "Package represents a package", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "CreatedAt" + }, + "creator": { + "$ref": "#/definitions/User" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "owner": { + "$ref": "#/definitions/User" + }, + "repository": { + "$ref": "#/definitions/Repository" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "version": { + "type": "string", + "x-go-name": "Version" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PackageFile": { + "description": "PackageFile represents a package file", + "type": "object", + "properties": { + "Size": { + "type": "integer", + "format": "int64" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "md5": { + "type": "string", + "x-go-name": "HashMD5" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "sha1": { + "type": "string", + "x-go-name": "HashSHA1" + }, + "sha256": { + "type": "string", + "x-go-name": "HashSHA256" + }, + "sha512": { + "type": "string", + "x-go-name": "HashSHA512" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PayloadCommit": { + "description": "PayloadCommit represents a commit", + "type": "object", + "properties": { + "added": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Added" + }, + "author": { + "$ref": "#/definitions/PayloadUser" + }, + "committer": { + "$ref": "#/definitions/PayloadUser" + }, + "id": { + "description": "sha1 hash of the commit", + "type": "string", + "x-go-name": "ID" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "modified": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Modified" + }, + "removed": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Removed" + }, + "timestamp": { + "type": "string", + "format": "date-time", + "x-go-name": "Timestamp" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PayloadCommitVerification": { + "description": "PayloadCommitVerification represents the GPG verification of a commit", + "type": "object", + "properties": { + "payload": { + "type": "string", + "x-go-name": "Payload" + }, + "reason": { + "type": "string", + "x-go-name": "Reason" + }, + "signature": { + "type": "string", + "x-go-name": "Signature" + }, + "signer": { + "$ref": "#/definitions/PayloadUser" + }, + "verified": { + "type": "boolean", + "x-go-name": "Verified" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PayloadUser": { + "description": "PayloadUser represents the author or committer of a commit", + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "name": { + "description": "Full name of the commit author", + "type": "string", + "x-go-name": "Name" + }, + "username": { + "type": "string", + "x-go-name": "UserName" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Permission": { + "description": "Permission represents a set of permissions", + "type": "object", + "properties": { + "admin": { + "type": "boolean", + "x-go-name": "Admin" + }, + "pull": { + "type": "boolean", + "x-go-name": "Pull" + }, + "push": { + "type": "boolean", + "x-go-name": "Push" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PublicKey": { + "description": "PublicKey publickey is a user key to push code to repository", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "fingerprint": { + "type": "string", + "x-go-name": "Fingerprint" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "key": { + "type": "string", + "x-go-name": "Key" + }, + "key_type": { + "type": "string", + "x-go-name": "KeyType" + }, + "read_only": { + "type": "boolean", + "x-go-name": "ReadOnly" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PullRequest": { + "description": "PullRequest represents a pull request", + "type": "object", + "properties": { + "additions": { + "type": "integer", + "format": "int64", + "x-go-name": "Additions" + }, + "allow_maintainer_edit": { + "type": "boolean", + "x-go-name": "AllowMaintainerEdit" + }, + "assignee": { + "$ref": "#/definitions/User" + }, + "assignees": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + }, + "x-go-name": "Assignees" + }, + "base": { + "$ref": "#/definitions/PRBranchInfo" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "changed_files": { + "type": "integer", + "format": "int64", + "x-go-name": "ChangedFiles" + }, + "closed_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Closed" + }, + "comments": { + "type": "integer", + "format": "int64", + "x-go-name": "Comments" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "deletions": { + "type": "integer", + "format": "int64", + "x-go-name": "Deletions" + }, + "diff_url": { + "type": "string", + "format": "url", + "x-go-name": "DiffURL" + }, + "draft": { + "type": "boolean", + "x-go-name": "Draft" + }, + "due_date": { + "type": "string", + "format": "date-time", + "x-go-name": "Deadline" + }, + "head": { + "$ref": "#/definitions/PRBranchInfo" + }, + "html_url": { + "format": "url", + "type": "string", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "is_locked": { + "type": "boolean", + "x-go-name": "IsLocked" + }, + "labels": { + "type": "array", + "items": { + "$ref": "#/definitions/Label" + }, + "x-go-name": "Labels" + }, + "merge_base": { + "type": "string", + "x-go-name": "MergeBase" + }, + "merge_commit_sha": { + "type": "string", + "x-go-name": "MergedCommitID" + }, + "mergeable": { + "type": "boolean", + "x-go-name": "Mergeable" + }, + "merged": { + "type": "boolean", + "x-go-name": "HasMerged" + }, + "merged_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Merged" + }, + "merged_by": { + "$ref": "#/definitions/User" + }, + "milestone": { + "$ref": "#/definitions/Milestone" + }, + "number": { + "type": "integer", + "format": "int64", + "x-go-name": "Index" + }, + "patch_url": { + "type": "string", + "format": "url", + "x-go-name": "PatchURL" + }, + "pin_order": { + "type": "integer", + "format": "int64", + "x-go-name": "PinOrder" + }, + "requested_reviewers": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + }, + "x-go-name": "RequestedReviewers" + }, + "review_comments": { + "description": "number of review comments made on the diff of a PR review (not including comments on commits or issues in a PR)", + "type": "integer", + "format": "int64", + "x-go-name": "ReviewComments" + }, + "state": { + "$ref": "#/definitions/StateType" + }, + "title": { + "type": "string", + "x-go-name": "Title" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs", + "x-parse-with": { + "requested_reviewers": "requested_reviewers_ignore_null" + } + }, + "PullRequestMeta": { + "description": "PullRequestMeta PR info if an issue is a PR", + "type": "object", + "properties": { + "draft": { + "type": "boolean", + "x-go-name": "IsWorkInProgress" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "merged": { + "type": "boolean", + "x-go-name": "HasMerged" + }, + "merged_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Merged" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PullReview": { + "description": "PullReview represents a pull request review", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "comments_count": { + "type": "integer", + "format": "int64", + "x-go-name": "CodeCommentsCount" + }, + "commit_id": { + "type": "string", + "x-go-name": "CommitID" + }, + "dismissed": { + "type": "boolean", + "x-go-name": "Dismissed" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "official": { + "type": "boolean", + "x-go-name": "Official" + }, + "pull_request_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLPullURL" + }, + "stale": { + "type": "boolean", + "x-go-name": "Stale" + }, + "state": { + "$ref": "#/definitions/ReviewStateType" + }, + "submitted_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Submitted" + }, + "team": { + "$ref": "#/definitions/Team" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PullReviewComment": { + "description": "PullReviewComment represents a comment on a pull request review", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "commit_id": { + "type": "string", + "x-go-name": "CommitID" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "diff_hunk": { + "type": "string", + "x-go-name": "DiffHunk" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "original_commit_id": { + "type": "string", + "x-go-name": "OrigCommitID" + }, + "original_position": { + "type": "integer", + "format": "uint64", + "x-go-name": "OldLineNum" + }, + "path": { + "type": "string", + "x-go-name": "Path" + }, + "position": { + "type": "integer", + "format": "uint64", + "x-go-name": "LineNum" + }, + "pull_request_review_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ReviewID" + }, + "pull_request_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLPullURL" + }, + "resolver": { + "$ref": "#/definitions/User" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PullReviewRequestOptions": { + "description": "PullReviewRequestOptions are options to add or remove pull review requests", + "type": "object", + "properties": { + "reviewers": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Reviewers" + }, + "team_reviewers": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "TeamReviewers" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "PushMirror": { + "description": "PushMirror represents information of a push mirror", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "CreatedUnix" + }, + "interval": { + "type": "string", + "x-go-name": "Interval" + }, + "last_error": { + "type": "string", + "x-go-name": "LastError" + }, + "last_update": { + "type": "string", + "format": "date-time", + "x-go-name": "LastUpdateUnix" + }, + "remote_address": { + "type": "string", + "x-go-name": "RemoteAddress" + }, + "remote_name": { + "type": "string", + "x-go-name": "RemoteName" + }, + "repo_name": { + "type": "string", + "x-go-name": "RepoName" + }, + "sync_on_commit": { + "type": "boolean", + "x-go-name": "SyncOnCommit" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Reaction": { + "description": "Reaction contain one reaction", + "type": "object", + "properties": { + "content": { + "type": "string", + "x-go-name": "Reaction" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Reference": { + "type": "object", + "title": "Reference represents a Git reference.", + "properties": { + "object": { + "$ref": "#/definitions/GitObject" + }, + "ref": { + "type": "string", + "x-go-name": "Ref" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Release": { + "description": "Release represents a repository release", + "type": "object", + "properties": { + "archive_download_count": { + "$ref": "#/definitions/TagArchiveDownloadCount" + }, + "assets": { + "type": "array", + "items": { + "$ref": "#/definitions/Attachment" + }, + "x-go-name": "Attachments" + }, + "author": { + "$ref": "#/definitions/User" + }, + "body": { + "type": "string", + "x-go-name": "Note" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "CreatedAt" + }, + "draft": { + "type": "boolean", + "x-go-name": "IsDraft" + }, + "hide_archive_links": { + "type": "boolean", + "x-go-name": "HideArchiveLinks" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Title" + }, + "prerelease": { + "type": "boolean", + "x-go-name": "IsPrerelease" + }, + "published_at": { + "type": "string", + "format": "date-time", + "x-go-name": "PublishedAt" + }, + "tag_name": { + "type": "string", + "x-go-name": "TagName" + }, + "tarball_url": { + "type": "string", + "format": "url", + "x-go-name": "TarURL" + }, + "target_commitish": { + "type": "string", + "x-go-name": "Target" + }, + "upload_url": { + "type": "string", + "format": "url", + "x-go-name": "UploadURL" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "zipball_url": { + "format": "url", + "type": "string", + "x-go-name": "ZipURL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RenameUserOption": { + "description": "RenameUserOption options when renaming a user", + "type": "object", + "required": ["new_username"], + "properties": { + "new_username": { + "description": "New username for this user. This name cannot be in use yet by any other user.", + "type": "string", + "uniqueItems": true, + "x-go-name": "NewName" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ReplaceFlagsOption": { + "description": "ReplaceFlagsOption options when replacing the flags of a repository", + "type": "object", + "properties": { + "flags": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Flags" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RepoCollaboratorPermission": { + "description": "RepoCollaboratorPermission to get repository permission for a collaborator", + "type": "object", + "properties": { + "permission": { + "type": "string", + "x-go-name": "Permission" + }, + "role_name": { + "type": "string", + "x-go-name": "RoleName" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RepoCommit": { + "type": "object", + "title": "RepoCommit contains information of a commit in the context of a repository.", + "properties": { + "author": { + "$ref": "#/definitions/CommitUser" + }, + "committer": { + "$ref": "#/definitions/CommitUser" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "tree": { + "$ref": "#/definitions/CommitMeta" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "verification": { + "$ref": "#/definitions/PayloadCommitVerification" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RepoTopicOptions": { + "description": "RepoTopicOptions a collection of repo topic names", + "type": "object", + "properties": { + "topics": { + "description": "list of topic names", + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Topics" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RepoTransfer": { + "description": "RepoTransfer represents a pending repo transfer", + "type": "object", + "properties": { + "doer": { + "$ref": "#/definitions/User" + }, + "recipient": { + "$ref": "#/definitions/User" + }, + "teams": { + "type": "array", + "items": { + "$ref": "#/definitions/Team" + }, + "x-go-name": "Teams" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Repository": { + "description": "Repository represents a repository", + "type": "object", + "properties": { + "allow_fast_forward_only_merge": { + "type": "boolean", + "x-go-name": "AllowFastForwardOnly" + }, + "allow_merge_commits": { + "type": "boolean", + "x-go-name": "AllowMerge" + }, + "allow_rebase": { + "type": "boolean", + "x-go-name": "AllowRebase" + }, + "allow_rebase_explicit": { + "type": "boolean", + "x-go-name": "AllowRebaseMerge" + }, + "allow_rebase_update": { + "type": "boolean", + "x-go-name": "AllowRebaseUpdate" + }, + "allow_squash_merge": { + "type": "boolean", + "x-go-name": "AllowSquash" + }, + "archived": { + "type": "boolean", + "x-go-name": "Archived" + }, + "archived_at": { + "type": "string", + "format": "date-time", + "x-go-name": "ArchivedAt" + }, + "avatar_url": { + "type": "string", + "format": "url", + "x-go-name": "AvatarURL" + }, + "clone_url": { + "type": "string", + "format": "url", + "x-go-name": "CloneURL" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "default_allow_maintainer_edit": { + "type": "boolean", + "x-go-name": "DefaultAllowMaintainerEdit" + }, + "default_branch": { + "type": "string", + "x-go-name": "DefaultBranch" + }, + "default_delete_branch_after_merge": { + "type": "boolean", + "x-go-name": "DefaultDeleteBranchAfterMerge" + }, + "default_merge_style": { + "$ref": "#/definitions/DefaultMergeStyle" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "empty": { + "type": "boolean", + "x-go-name": "Empty" + }, + "external_tracker": { + "$ref": "#/definitions/ExternalTracker" + }, + "external_wiki": { + "$ref": "#/definitions/ExternalWiki" + }, + "fork": { + "type": "boolean", + "x-go-name": "Fork" + }, + "forks_count": { + "type": "integer", + "format": "int64", + "x-go-name": "Forks" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "globally_editable_wiki": { + "type": "boolean", + "x-go-name": "GloballyEditableWiki" + }, + "has_actions": { + "type": "boolean", + "x-go-name": "HasActions" + }, + "has_issues": { + "type": "boolean", + "x-go-name": "HasIssues" + }, + "has_packages": { + "type": "boolean", + "x-go-name": "HasPackages" + }, + "has_projects": { + "type": "boolean", + "x-go-name": "HasProjects" + }, + "has_pull_requests": { + "type": "boolean", + "x-go-name": "HasPullRequests" + }, + "has_releases": { + "type": "boolean", + "x-go-name": "HasReleases" + }, + "has_wiki": { + "type": "boolean", + "x-go-name": "HasWiki" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "ignore_whitespace_conflicts": { + "type": "boolean", + "x-go-name": "IgnoreWhitespaceConflicts" + }, + "internal": { + "type": "boolean", + "x-go-name": "Internal" + }, + "internal_tracker": { + "$ref": "#/definitions/InternalTracker" + }, + "language": { + "type": "string", + "x-go-name": "Language" + }, + "languages_url": { + "type": "string", + "format": "url", + "x-go-name": "LanguagesURL" + }, + "link": { + "type": "string", + "x-go-name": "Link" + }, + "mirror": { + "type": "boolean", + "x-go-name": "Mirror" + }, + "mirror_interval": { + "type": "string", + "x-go-name": "MirrorInterval" + }, + "mirror_updated": { + "type": "string", + "format": "date-time", + "x-go-name": "MirrorUpdated" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "object_format_name": { + "$ref": "#/definitions/ObjectFormatName" + }, + "open_issues_count": { + "type": "integer", + "format": "int64", + "x-go-name": "OpenIssues" + }, + "open_pr_counter": { + "type": "integer", + "format": "int64", + "x-go-name": "OpenPulls" + }, + "original_url": { + "type": "string", + "format": "url", + "x-go-name": "OriginalURL" + }, + "owner": { + "$ref": "#/definitions/User" + }, + "parent": { + "$ref": "#/definitions/Repository" + }, + "permissions": { + "$ref": "#/definitions/Permission" + }, + "private": { + "type": "boolean", + "x-go-name": "Private" + }, + "release_counter": { + "type": "integer", + "format": "int64", + "x-go-name": "Releases" + }, + "repo_transfer": { + "$ref": "#/definitions/RepoTransfer" + }, + "size": { + "type": "integer", + "format": "int64", + "x-go-name": "Size" + }, + "ssh_url": { + "type": "string", + "format": "ssh-url", + "x-go-name": "SSHURL" + }, + "stars_count": { + "type": "integer", + "format": "int64", + "x-go-name": "Stars" + }, + "template": { + "type": "boolean", + "x-go-name": "Template" + }, + "topics": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Topics" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + }, + "watchers_count": { + "type": "integer", + "format": "int64", + "x-go-name": "Watchers" + }, + "website": { + "type": "string", + "x-go-name": "Website" + }, + "wiki_branch": { + "type": "string", + "x-go-name": "WikiBranch" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "RepositoryMeta": { + "description": "RepositoryMeta basic repository information", + "type": "object", + "properties": { + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "owner": { + "type": "string", + "x-go-name": "Owner" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ReviewStateType": { + "description": "ReviewStateType review state type", + "type": "string", + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "SearchResults": { + "description": "SearchResults results of a successful search", + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/Repository" + }, + "x-go-name": "Data" + }, + "ok": { + "type": "boolean", + "x-go-name": "OK" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Secret": { + "description": "Secret represents a secret", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "name": { + "description": "the secret's name", + "type": "string", + "x-go-name": "Name" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "ServerVersion": { + "description": "ServerVersion wraps the version of the server", + "type": "object", + "properties": { + "version": { + "type": "string", + "x-go-name": "Version" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "StateType": { + "description": "StateType issue state type", + "type": "string", + "enum": [ + "open", + "closed" + ], + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "StopWatch": { + "description": "StopWatch represent a running stopwatch", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "duration": { + "type": "string", + "x-go-name": "Duration" + }, + "issue_index": { + "type": "integer", + "format": "int64", + "x-go-name": "IssueIndex" + }, + "issue_title": { + "type": "string", + "x-go-name": "IssueTitle" + }, + "repo_name": { + "type": "string", + "x-go-name": "RepoName" + }, + "repo_owner_name": { + "type": "string", + "x-go-name": "RepoOwnerName" + }, + "seconds": { + "type": "integer", + "format": "int64", + "x-go-name": "Seconds" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "SubmitPullReviewOptions": { + "description": "SubmitPullReviewOptions are options to submit a pending pull review", + "type": "object", + "properties": { + "body": { + "type": "string", + "x-go-name": "Body" + }, + "event": { + "$ref": "#/definitions/ReviewStateType" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Tag": { + "description": "Tag represents a repository tag", + "type": "object", + "properties": { + "archive_download_count": { + "$ref": "#/definitions/TagArchiveDownloadCount" + }, + "commit": { + "$ref": "#/definitions/CommitMeta" + }, + "id": { + "type": "string", + "x-go-name": "ID" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "tarball_url": { + "type": "string", + "format": "url", + "x-go-name": "TarballURL" + }, + "zipball_url": { + "type": "string", + "format": "url", + "x-go-name": "ZipballURL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TagArchiveDownloadCount": { + "description": "TagArchiveDownloadCount counts how many times a archive was downloaded", + "type": "object", + "properties": { + "tar_gz": { + "type": "integer", + "format": "int64", + "x-go-name": "TarGz" + }, + "zip": { + "type": "integer", + "format": "int64", + "x-go-name": "Zip" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TagProtection": { + "description": "TagProtection represents a tag protection", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "name_pattern": { + "type": "string", + "x-go-name": "NamePattern" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "whitelist_teams": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistTeams" + }, + "whitelist_usernames": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "WhitelistUsernames" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "Team": { + "description": "Team represents a team in an organization", + "type": "object", + "properties": { + "can_create_org_repo": { + "type": "boolean", + "x-go-name": "CanCreateOrgRepo" + }, + "description": { + "type": "string", + "x-go-name": "Description" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "includes_all_repositories": { + "type": "boolean", + "x-go-name": "IncludesAllRepositories" + }, + "name": { + "type": "string", + "x-go-name": "Name" + }, + "organization": { + "$ref": "#/definitions/Organization" + }, + "permission": { + "type": "string", + "enum": ["none", "read", "write", "admin", "owner"], + "x-go-name": "Permission" + }, + "units": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "Units", + "example": [ + "repo.code", + "repo.issues", + "repo.ext_issues", + "repo.wiki", + "repo.pulls", + "repo.releases", + "repo.projects", + "repo.ext_wiki" + ] + }, + "units_map": { + "type": "object", + "additionalProperties": { + "type": "string" + }, + "x-go-name": "UnitsMap", + "example": { + "repo.code": "read", + "repo.ext_issues": "none", + "repo.ext_wiki": "none", + "repo.issues": "write", + "repo.projects": "none", + "repo.pulls": "owner", + "repo.releases": "none", + "repo.wiki": "admin" + } + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TimeStamp": { + "description": "TimeStamp defines a timestamp", + "type": "integer", + "format": "int64", + "x-go-package": "code.gitea.io/gitea/modules/timeutil" + }, + "TimelineComment": { + "description": "TimelineComment represents a timeline comment (comment of any type) on a commit or issue", + "type": "object", + "properties": { + "assignee": { + "$ref": "#/definitions/User" + }, + "assignee_team": { + "$ref": "#/definitions/Team" + }, + "body": { + "type": "string", + "x-go-name": "Body" + }, + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "dependent_issue": { + "$ref": "#/definitions/Issue" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "issue_url": { + "type": "string", + "format": "url", + "x-go-name": "IssueURL" + }, + "label": { + "$ref": "#/definitions/Label" + }, + "milestone": { + "$ref": "#/definitions/Milestone" + }, + "new_ref": { + "type": "string", + "x-go-name": "NewRef" + }, + "new_title": { + "type": "string", + "x-go-name": "NewTitle" + }, + "old_milestone": { + "$ref": "#/definitions/Milestone" + }, + "old_project_id": { + "type": "integer", + "format": "int64", + "x-go-name": "OldProjectID" + }, + "old_ref": { + "type": "string", + "x-go-name": "OldRef" + }, + "old_title": { + "type": "string", + "x-go-name": "OldTitle" + }, + "project_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ProjectID" + }, + "pull_request_url": { + "type": "string", + "format": "url", + "x-go-name": "PRURL" + }, + "ref_action": { + "type": "string", + "x-go-name": "RefAction" + }, + "ref_comment": { + "$ref": "#/definitions/Comment" + }, + "ref_commit_sha": { + "description": "commit SHA where issue/PR was referenced", + "type": "string", + "x-go-name": "RefCommitSHA" + }, + "ref_issue": { + "$ref": "#/definitions/Issue" + }, + "removed_assignee": { + "description": "whether the assignees were removed or added", + "type": "boolean", + "x-go-name": "RemovedAssignee" + }, + "resolve_doer": { + "$ref": "#/definitions/User" + }, + "review_id": { + "type": "integer", + "format": "int64", + "x-go-name": "ReviewID" + }, + "tracked_time": { + "$ref": "#/definitions/TrackedTime" + }, + "type": { + "type": "string", + "x-go-name": "Type" + }, + "updated_at": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + }, + "user": { + "$ref": "#/definitions/User" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TopicName": { + "description": "TopicName a list of repo topic names", + "type": "object", + "properties": { + "topics": { + "type": "array", + "items": { + "type": "string" + }, + "x-go-name": "TopicNames" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TopicResponse": { + "description": "TopicResponse for returning topics", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "repo_count": { + "type": "integer", + "format": "int64", + "x-go-name": "RepoCount" + }, + "topic_name": { + "type": "string", + "x-go-name": "Name" + }, + "updated": { + "type": "string", + "format": "date-time", + "x-go-name": "Updated" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TrackedTime": { + "description": "TrackedTime worked time for an issue / pr", + "type": "object", + "properties": { + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "id": { + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "issue": { + "$ref": "#/definitions/Issue" + }, + "issue_id": { + "description": "deprecated (only for backwards compatibility)", + "type": "integer", + "format": "int64", + "x-go-name": "IssueID" + }, + "time": { + "description": "Time in seconds", + "type": "integer", + "format": "int64", + "x-go-name": "Time" + }, + "user_id": { + "description": "deprecated (only for backwards compatibility)", + "type": "integer", + "format": "int64", + "x-go-name": "UserID" + }, + "user_name": { + "type": "string", + "x-go-name": "UserName" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "TransferRepoOption": { + "description": "TransferRepoOption options when transfer a repository's ownership", + "type": "object", + "required": ["new_owner"], + "properties": { + "new_owner": { + "type": "string", + "x-go-name": "NewOwner" + }, + "team_ids": { + "description": "ID of the team or teams to add to the repository. Teams can only be added to organization-owned repositories.", + "type": "array", + "items": { + "type": "integer", + "format": "int64" + }, + "x-go-name": "TeamIDs" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UpdateFileOptions": { + "description": "UpdateFileOptions options for updating files\nNote: `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": "object", + "required": ["sha", "content"], + "properties": { + "author": { + "$ref": "#/definitions/Identity" + }, + "branch": { + "description": "branch (optional) to base this file from. if not given, the default branch is used", + "type": "string", + "x-go-name": "BranchName" + }, + "committer": { + "$ref": "#/definitions/Identity" + }, + "content": { + "description": "content must be base64 encoded", + "type": "string", + "x-go-name": "ContentBase64" + }, + "dates": { + "$ref": "#/definitions/CommitDateOptions" + }, + "from_path": { + "description": "from_path (optional) is the path of the original file which will be moved/renamed to the path in the URL", + "type": "string", + "x-go-name": "FromPath" + }, + "message": { + "description": "message (optional) for the commit of this file. if not supplied, a default message will be used", + "type": "string", + "x-go-name": "Message" + }, + "new_branch": { + "description": "new_branch (optional) will make a new branch from `branch` before creating the file", + "type": "string", + "x-go-name": "NewBranchName" + }, + "sha": { + "description": "sha is the SHA for the file that already exists", + "type": "string", + "x-go-name": "SHA" + }, + "signoff": { + "description": "Add a Signed-off-by trailer by the committer at the end of the commit log message.", + "type": "boolean", + "x-go-name": "Signoff" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UpdateRepoAvatarOption": { + "description": "UpdateRepoAvatarUserOption options when updating the repo avatar", + "type": "object", + "properties": { + "image": { + "description": "image must be base64 encoded", + "type": "string", + "x-go-name": "Image" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UpdateUserAvatarOption": { + "description": "UpdateUserAvatarUserOption options when updating the user avatar", + "type": "object", + "properties": { + "image": { + "description": "image must be base64 encoded", + "type": "string", + "x-go-name": "Image" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UpdateVariableOption": { + "description": "UpdateVariableOption the option when updating variable", + "type": "object", + "required": ["value"], + "properties": { + "name": { + "description": "New name for the variable. If the field is empty, the variable name won't be updated.", + "type": "string", + "x-go-name": "Name" + }, + "value": { + "description": "Value of the variable to update", + "type": "string", + "x-go-name": "Value" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "User": { + "description": "User represents a user", + "type": "object", + "properties": { + "active": { + "description": "Is user active", + "type": "boolean", + "x-go-name": "IsActive" + }, + "avatar_url": { + "description": "URL to the user's avatar", + "type": "string", + "format": "url", + "x-go-name": "AvatarURL" + }, + "created": { + "type": "string", + "format": "date-time", + "x-go-name": "Created" + }, + "description": { + "description": "the user's description", + "type": "string", + "x-go-name": "Description" + }, + "email": { + "type": "string", + "format": "email", + "x-go-name": "Email" + }, + "followers_count": { + "description": "user counts", + "type": "integer", + "format": "int64", + "x-go-name": "Followers" + }, + "following_count": { + "type": "integer", + "format": "int64", + "x-go-name": "Following" + }, + "full_name": { + "description": "the user's full name", + "type": "string", + "x-go-name": "FullName" + }, + "html_url": { + "description": "URL to the user's gitea page", + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "id": { + "description": "the user's id", + "type": "integer", + "format": "int64", + "x-go-name": "ID" + }, + "is_admin": { + "description": "Is the user an administrator", + "type": "boolean", + "x-go-name": "IsAdmin" + }, + "language": { + "description": "User locale", + "type": "string", + "x-go-name": "Language" + }, + "last_login": { + "type": "string", + "format": "date-time", + "x-go-name": "LastLogin" + }, + "location": { + "description": "the user's location", + "type": "string", + "x-go-name": "Location" + }, + "login": { + "description": "the user's username", + "type": "string", + "x-go-name": "UserName" + }, + "login_name": { + "description": "the user's authentication sign-in name.", + "type": "string", + "default": "empty", + "x-go-name": "LoginName" + }, + "prohibit_login": { + "description": "Is user login prohibited", + "type": "boolean", + "x-go-name": "ProhibitLogin" + }, + "pronouns": { + "description": "the user's pronouns", + "type": "string", + "x-go-name": "Pronouns" + }, + "restricted": { + "description": "Is user restricted", + "type": "boolean", + "x-go-name": "Restricted" + }, + "source_id": { + "description": "The ID of the user's Authentication Source", + "type": "integer", + "format": "int64", + "x-go-name": "SourceID" + }, + "starred_repos_count": { + "type": "integer", + "format": "int64", + "x-go-name": "StarredRepos" + }, + "visibility": { + "description": "User visibility level option: public, limited, private", + "type": "string", + "x-go-name": "Visibility" + }, + "website": { + "description": "the user's website", + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UserHeatmapData": { + "description": "UserHeatmapData represents the data needed to create a heatmap", + "type": "object", + "properties": { + "contributions": { + "type": "integer", + "format": "int64", + "x-go-name": "Contributions" + }, + "timestamp": { + "$ref": "#/definitions/TimeStamp" + } + }, + "x-go-package": "code.gitea.io/gitea/models/activities" + }, + "UserSettings": { + "description": "UserSettings represents user settings", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "diff_view_style": { + "type": "string", + "x-go-name": "DiffViewStyle" + }, + "enable_repo_unit_hints": { + "type": "boolean", + "x-go-name": "EnableRepoUnitHints" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "hide_activity": { + "type": "boolean", + "x-go-name": "HideActivity" + }, + "hide_email": { + "description": "Privacy", + "type": "boolean", + "x-go-name": "HideEmail" + }, + "language": { + "type": "string", + "x-go-name": "Language" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "pronouns": { + "type": "string", + "x-go-name": "Pronouns" + }, + "theme": { + "type": "string", + "x-go-name": "Theme" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "UserSettingsOptions": { + "description": "UserSettingsOptions represents options to change user settings", + "type": "object", + "properties": { + "description": { + "type": "string", + "x-go-name": "Description" + }, + "diff_view_style": { + "type": "string", + "x-go-name": "DiffViewStyle" + }, + "enable_repo_unit_hints": { + "type": "boolean", + "x-go-name": "EnableRepoUnitHints" + }, + "full_name": { + "type": "string", + "x-go-name": "FullName" + }, + "hide_activity": { + "type": "boolean", + "x-go-name": "HideActivity" + }, + "hide_email": { + "description": "Privacy", + "type": "boolean", + "x-go-name": "HideEmail" + }, + "language": { + "type": "string", + "x-go-name": "Language" + }, + "location": { + "type": "string", + "x-go-name": "Location" + }, + "pronouns": { + "type": "string", + "x-go-name": "Pronouns" + }, + "theme": { + "type": "string", + "x-go-name": "Theme" + }, + "website": { + "type": "string", + "x-go-name": "Website" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "WatchInfo": { + "description": "WatchInfo represents an API watch status of one repository", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time", + "x-go-name": "CreatedAt" + }, + "ignored": { + "type": "boolean", + "x-go-name": "Ignored" + }, + "reason": { + "x-go-name": "Reason" + }, + "repository_url": { + "type": "string", + "format": "url", + "x-go-name": "RepositoryURL" + }, + "subscribed": { + "type": "boolean", + "x-go-name": "Subscribed" + }, + "url": { + "type": "string", + "format": "url", + "x-go-name": "URL" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "WikiCommit": { + "description": "WikiCommit page commit/revision", + "type": "object", + "properties": { + "author": { + "$ref": "#/definitions/CommitUser" + }, + "commiter": { + "$ref": "#/definitions/CommitUser" + }, + "message": { + "type": "string", + "x-go-name": "Message" + }, + "sha": { + "type": "string", + "x-go-name": "ID" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "WikiCommitList": { + "description": "WikiCommitList commit/revision list", + "type": "object", + "properties": { + "commits": { + "type": "array", + "items": { + "$ref": "#/definitions/WikiCommit" + }, + "x-go-name": "WikiCommits" + }, + "count": { + "type": "integer", + "format": "int64", + "x-go-name": "Count" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "WikiPage": { + "description": "WikiPage a wiki page", + "type": "object", + "properties": { + "commit_count": { + "type": "integer", + "format": "int64", + "x-go-name": "CommitCount" + }, + "content_base64": { + "description": "Page content, base64 encoded", + "type": "string", + "x-go-name": "ContentBase64" + }, + "footer": { + "type": "string", + "x-go-name": "Footer" + }, + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "last_commit": { + "$ref": "#/definitions/WikiCommit" + }, + "sidebar": { + "type": "string", + "x-go-name": "Sidebar" + }, + "sub_url": { + "type": "string", + "x-go-name": "SubURL" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + }, + "WikiPageMetaData": { + "description": "WikiPageMetaData wiki page meta information", + "type": "object", + "properties": { + "html_url": { + "type": "string", + "format": "url", + "x-go-name": "HTMLURL" + }, + "last_commit": { + "$ref": "#/definitions/WikiCommit" + }, + "sub_url": { + "type": "string", + "x-go-name": "SubURL" + }, + "title": { + "type": "string", + "x-go-name": "Title" + } + }, + "x-go-package": "code.gitea.io/gitea/modules/structs" + } + }, + "responses": { + "AccessToken": { + "description": "AccessToken represents an API access token.", + "schema": { + "$ref": "#/definitions/AccessToken" + } + }, + "AccessTokenList": { + "description": "AccessTokenList represents a list of API access token.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/AccessToken" + } + } + }, + "ActionVariable": { + "description": "ActionVariable", + "schema": { + "$ref": "#/definitions/ActionVariable" + } + }, + "ActivityFeedsList": { + "description": "ActivityFeedsList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Activity" + } + } + }, + "ActivityPub": { + "description": "ActivityPub", + "schema": { + "$ref": "#/definitions/ActivityPub" + } + }, + "AnnotatedTag": { + "description": "AnnotatedTag", + "schema": { + "$ref": "#/definitions/AnnotatedTag" + } + }, + "Attachment": { + "description": "Attachment", + "schema": { + "$ref": "#/definitions/Attachment" + } + }, + "AttachmentList": { + "description": "AttachmentList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Attachment" + } + } + }, + "BlockedUserList": { + "description": "BlockedUserList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/BlockedUser" + } + } + }, + "Branch": { + "description": "Branch", + "schema": { + "$ref": "#/definitions/Branch" + } + }, + "BranchList": { + "description": "BranchList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Branch" + } + } + }, + "BranchProtection": { + "description": "BranchProtection", + "schema": { + "$ref": "#/definitions/BranchProtection" + } + }, + "BranchProtectionList": { + "description": "BranchProtectionList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/BranchProtection" + } + } + }, + "ChangedFileList": { + "description": "ChangedFileList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/ChangedFile" + } + }, + "headers": { + "X-HasMore": { + "type": "boolean", + "description": "True if there is another page" + }, + "X-Page": { + "type": "integer", + "format": "int64", + "description": "The current page" + }, + "X-PageCount": { + "type": "integer", + "format": "int64", + "description": "Total number of pages" + }, + "X-PerPage": { + "type": "integer", + "format": "int64", + "description": "Commits per page" + }, + "X-Total-Count": { + "type": "integer", + "format": "int64", + "description": "Total commit count" + } + } + }, + "CombinedStatus": { + "description": "CombinedStatus", + "schema": { + "$ref": "#/definitions/CombinedStatus" + } + }, + "Comment": { + "description": "Comment", + "schema": { + "$ref": "#/definitions/Comment" + } + }, + "CommentList": { + "description": "CommentList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Comment" + } + } + }, + "Commit": { + "description": "Commit", + "schema": { + "$ref": "#/definitions/Commit" + } + }, + "CommitList": { + "description": "CommitList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Commit" + } + }, + "headers": { + "X-HasMore": { + "type": "boolean", + "description": "True if there is another page" + }, + "X-Page": { + "type": "integer", + "format": "int64", + "description": "The current page" + }, + "X-PageCount": { + "type": "integer", + "format": "int64", + "description": "Total number of pages" + }, + "X-PerPage": { + "type": "integer", + "format": "int64", + "description": "Commits per page" + }, + "X-Total": { + "type": "integer", + "format": "int64", + "description": "Total commit count" + } + } + }, + "CommitStatus": { + "description": "CommitStatus", + "schema": { + "$ref": "#/definitions/CommitStatus" + } + }, + "CommitStatusList": { + "description": "CommitStatusList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/CommitStatus" + } + } + }, + "Compare": { + "description": "", + "schema": { + "$ref": "#/definitions/Compare" + } + }, + "ContentsListResponse": { + "description": "ContentsListResponse", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/ContentsResponse" + } + } + }, + "ContentsResponse": { + "description": "ContentsResponse", + "schema": { + "$ref": "#/definitions/ContentsResponse" + } + }, + "CronList": { + "description": "CronList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Cron" + } + } + }, + "DeployKey": { + "description": "DeployKey", + "schema": { + "$ref": "#/definitions/DeployKey" + } + }, + "DeployKeyList": { + "description": "DeployKeyList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/DeployKey" + } + } + }, + "EmailList": { + "description": "EmailList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Email" + } + } + }, + "EmptyRepository": { + "description": "EmptyRepository", + "schema": { + "$ref": "#/definitions/APIError" + } + }, + "FileDeleteResponse": { + "description": "FileDeleteResponse", + "schema": { + "$ref": "#/definitions/FileDeleteResponse" + } + }, + "FileResponse": { + "description": "FileResponse", + "schema": { + "$ref": "#/definitions/FileResponse" + } + }, + "FilesResponse": { + "description": "FilesResponse", + "schema": { + "$ref": "#/definitions/FilesResponse" + } + }, + "GPGKey": { + "description": "GPGKey", + "schema": { + "$ref": "#/definitions/GPGKey" + } + }, + "GPGKeyList": { + "description": "GPGKeyList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/GPGKey" + } + } + }, + "GeneralAPISettings": { + "description": "GeneralAPISettings", + "schema": { + "$ref": "#/definitions/GeneralAPISettings" + } + }, + "GeneralAttachmentSettings": { + "description": "GeneralAttachmentSettings", + "schema": { + "$ref": "#/definitions/GeneralAttachmentSettings" + } + }, + "GeneralRepoSettings": { + "description": "GeneralRepoSettings", + "schema": { + "$ref": "#/definitions/GeneralRepoSettings" + } + }, + "GeneralUISettings": { + "description": "GeneralUISettings", + "schema": { + "$ref": "#/definitions/GeneralUISettings" + } + }, + "GitBlobResponse": { + "description": "GitBlobResponse", + "schema": { + "$ref": "#/definitions/GitBlobResponse" + } + }, + "GitHook": { + "description": "GitHook", + "schema": { + "$ref": "#/definitions/GitHook" + } + }, + "GitHookList": { + "description": "GitHookList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/GitHook" + } + } + }, + "GitTreeResponse": { + "description": "GitTreeResponse", + "schema": { + "$ref": "#/definitions/GitTreeResponse" + } + }, + "GitignoreTemplateInfo": { + "description": "GitignoreTemplateInfo", + "schema": { + "$ref": "#/definitions/GitignoreTemplateInfo" + } + }, + "GitignoreTemplateList": { + "description": "GitignoreTemplateList", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "Hook": { + "description": "Hook", + "schema": { + "$ref": "#/definitions/Hook" + } + }, + "HookList": { + "description": "HookList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Hook" + } + } + }, + "Issue": { + "description": "Issue", + "schema": { + "$ref": "#/definitions/Issue" + } + }, + "IssueDeadline": { + "description": "IssueDeadline", + "schema": { + "$ref": "#/definitions/IssueDeadline" + } + }, + "IssueList": { + "description": "IssueList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Issue" + } + } + }, + "IssueTemplates": { + "description": "IssueTemplates", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/IssueTemplate" + } + } + }, + "Label": { + "description": "Label", + "schema": { + "$ref": "#/definitions/Label" + } + }, + "LabelList": { + "description": "LabelList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Label" + } + } + }, + "LabelTemplateInfo": { + "description": "LabelTemplateInfo", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/LabelTemplate" + } + } + }, + "LabelTemplateList": { + "description": "LabelTemplateList", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "LanguageStatistics": { + "description": "LanguageStatistics", + "schema": { + "type": "object", + "additionalProperties": { + "type": "integer", + "format": "int64" + } + } + }, + "LicenseTemplateInfo": { + "description": "LicenseTemplateInfo", + "schema": { + "$ref": "#/definitions/LicenseTemplateInfo" + } + }, + "LicenseTemplateList": { + "description": "LicenseTemplateList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/LicensesTemplateListEntry" + } + } + }, + "MarkdownRender": { + "description": "MarkdownRender is a rendered markdown document", + "schema": { + "type": "string" + } + }, + "MarkupRender": { + "description": "MarkupRender is a rendered markup document", + "schema": { + "type": "string" + } + }, + "Milestone": { + "description": "Milestone", + "schema": { + "$ref": "#/definitions/Milestone" + } + }, + "MilestoneList": { + "description": "MilestoneList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Milestone" + } + } + }, + "NodeInfo": { + "description": "NodeInfo", + "schema": { + "$ref": "#/definitions/NodeInfo" + } + }, + "Note": { + "description": "Note", + "schema": { + "$ref": "#/definitions/Note" + } + }, + "NotificationCount": { + "description": "Number of unread notifications", + "schema": { + "$ref": "#/definitions/NotificationCount" + } + }, + "NotificationThread": { + "description": "NotificationThread", + "schema": { + "$ref": "#/definitions/NotificationThread" + } + }, + "NotificationThreadList": { + "description": "NotificationThreadList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/NotificationThread" + } + } + }, + "OAuth2Application": { + "description": "OAuth2Application", + "schema": { + "$ref": "#/definitions/OAuth2Application" + } + }, + "OAuth2ApplicationList": { + "description": "OAuth2ApplicationList represents a list of OAuth2 applications.", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/OAuth2Application" + } + } + }, + "Organization": { + "description": "Organization", + "schema": { + "$ref": "#/definitions/Organization" + } + }, + "OrganizationList": { + "description": "OrganizationList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Organization" + } + } + }, + "OrganizationPermissions": { + "description": "OrganizationPermissions", + "schema": { + "$ref": "#/definitions/OrganizationPermissions" + } + }, + "Package": { + "description": "Package", + "schema": { + "$ref": "#/definitions/Package" + } + }, + "PackageFileList": { + "description": "PackageFileList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PackageFile" + } + } + }, + "PackageList": { + "description": "PackageList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Package" + } + } + }, + "PublicKey": { + "description": "PublicKey", + "schema": { + "$ref": "#/definitions/PublicKey" + } + }, + "PublicKeyList": { + "description": "PublicKeyList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PublicKey" + } + } + }, + "PullRequest": { + "description": "PullRequest", + "schema": { + "$ref": "#/definitions/PullRequest" + } + }, + "PullRequestList": { + "description": "PullRequestList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PullRequest" + } + } + }, + "PullReview": { + "description": "PullReview", + "schema": { + "$ref": "#/definitions/PullReview" + } + }, + "PullReviewComment": { + "description": "PullComment", + "schema": { + "$ref": "#/definitions/PullReviewComment" + } + }, + "PullReviewCommentList": { + "description": "PullCommentList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PullReviewComment" + } + } + }, + "PullReviewList": { + "description": "PullReviewList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PullReview" + } + } + }, + "PushMirror": { + "description": "PushMirror", + "schema": { + "$ref": "#/definitions/PushMirror" + } + }, + "PushMirrorList": { + "description": "PushMirrorList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/PushMirror" + } + } + }, + "Reaction": { + "description": "Reaction", + "schema": { + "$ref": "#/definitions/Reaction" + } + }, + "ReactionList": { + "description": "ReactionList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Reaction" + } + } + }, + "Reference": { + "description": "Reference", + "schema": { + "$ref": "#/definitions/Reference" + } + }, + "ReferenceList": { + "description": "ReferenceList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Reference" + } + } + }, + "RegistrationToken": { + "description": "RegistrationToken is a string used to register a runner with a server", + "headers": { + "token": { + "type": "string" + } + } + }, + "Release": { + "description": "Release", + "schema": { + "$ref": "#/definitions/Release" + } + }, + "ReleaseList": { + "description": "ReleaseList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Release" + } + } + }, + "RepoCollaboratorPermission": { + "description": "RepoCollaboratorPermission", + "schema": { + "$ref": "#/definitions/RepoCollaboratorPermission" + } + }, + "RepoIssueConfig": { + "description": "RepoIssueConfig", + "schema": { + "$ref": "#/definitions/IssueConfig" + } + }, + "RepoIssueConfigValidation": { + "description": "RepoIssueConfigValidation", + "schema": { + "$ref": "#/definitions/IssueConfigValidation" + } + }, + "RepoNewIssuePinsAllowed": { + "description": "RepoNewIssuePinsAllowed", + "schema": { + "$ref": "#/definitions/NewIssuePinsAllowed" + } + }, + "Repository": { + "description": "Repository", + "schema": { + "$ref": "#/definitions/Repository" + } + }, + "RepositoryList": { + "description": "RepositoryList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Repository" + } + } + }, + "SearchResults": { + "description": "SearchResults", + "schema": { + "$ref": "#/definitions/SearchResults" + } + }, + "Secret": { + "description": "Secret", + "schema": { + "$ref": "#/definitions/Secret" + } + }, + "SecretList": { + "description": "SecretList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Secret" + } + } + }, + "ServerVersion": { + "description": "ServerVersion", + "schema": { + "$ref": "#/definitions/ServerVersion" + } + }, + "StopWatch": { + "description": "StopWatch", + "schema": { + "$ref": "#/definitions/StopWatch" + } + }, + "StopWatchList": { + "description": "StopWatchList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/StopWatch" + } + } + }, + "StringSlice": { + "description": "StringSlice", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "Tag": { + "description": "Tag", + "schema": { + "$ref": "#/definitions/Tag" + } + }, + "TagList": { + "description": "TagList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Tag" + } + } + }, + "TagProtection": { + "description": "TagProtection", + "schema": { + "$ref": "#/definitions/TagProtection" + } + }, + "TagProtectionList": { + "description": "TagProtectionList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TagProtection" + } + } + }, + "TasksList": { + "description": "TasksList", + "schema": { + "$ref": "#/definitions/ActionTaskResponse" + } + }, + "Team": { + "description": "Team", + "schema": { + "$ref": "#/definitions/Team" + } + }, + "TeamList": { + "description": "TeamList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/Team" + } + } + }, + "TimelineList": { + "description": "TimelineList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TimelineComment" + } + } + }, + "TopicListResponse": { + "description": "TopicListResponse", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TopicResponse" + } + } + }, + "TopicNames": { + "description": "TopicNames", + "schema": { + "$ref": "#/definitions/TopicName" + } + }, + "TrackedTime": { + "description": "TrackedTime", + "schema": { + "$ref": "#/definitions/TrackedTime" + } + }, + "TrackedTimeList": { + "description": "TrackedTimeList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/TrackedTime" + } + } + }, + "User": { + "description": "User", + "schema": { + "$ref": "#/definitions/User" + } + }, + "UserHeatmapData": { + "description": "UserHeatmapData", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/UserHeatmapData" + } + } + }, + "UserList": { + "description": "UserList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/User" + } + } + }, + "UserSettings": { + "description": "UserSettings", + "schema": { + "$ref": "#/definitions/UserSettings" + } + }, + "VariableList": { + "description": "VariableList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/ActionVariable" + } + } + }, + "WatchInfo": { + "description": "WatchInfo", + "schema": { + "$ref": "#/definitions/WatchInfo" + } + }, + "WikiCommitList": { + "description": "WikiCommitList", + "schema": { + "$ref": "#/definitions/WikiCommitList" + } + }, + "WikiPage": { + "description": "WikiPage", + "schema": { + "$ref": "#/definitions/WikiPage" + } + }, + "WikiPageList": { + "description": "WikiPageList", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/WikiPageMetaData" + } + } + }, + "conflict": { + "description": "APIConflict is a conflict empty response" + }, + "empty": { + "description": "APIEmpty is an empty response" + }, + "error": { + "description": "APIError is error format response", + "headers": { + "message": { + "type": "string" + }, + "url": { + "type": "string", + "format": "url" + } + } + }, + "forbidden": { + "description": "APIForbiddenError is a forbidden error response", + "headers": { + "message": { + "type": "string" + }, + "url": { + "type": "string", + "format": "url" + } + } + }, + "invalidTopicsError": { + "description": "APIInvalidTopicsError is error format response to invalid topics", + "headers": { + "invalidTopics": { + "type": "array", + "items": { + "type": "string" + } + }, + "message": { + "type": "string" + } + } + }, + "notFound": { + "description": "APINotFound is a not found empty response" + }, + "parameterBodies": { + "description": "parameterBodies", + "schema": { + "$ref": "#/definitions/DispatchWorkflowOption" + } + }, + "redirect": { + "description": "APIRedirect is a redirect response" + }, + "repoArchivedError": { + "description": "APIRepoArchivedError is an error that is raised when an archived repo should be modified", + "headers": { + "message": { + "type": "string" + }, + "url": { + "type": "string", + "format": "url" + } + } + }, + "string": { + "description": "APIString is a string response", + "schema": { + "type": "string" + } + }, + "validationError": { + "description": "APIValidationError is error format response related to input validation", + "headers": { + "message": { + "type": "string" + }, + "url": { + "type": "string", + "format": "url" + } + } + } + }, + "securityDefinitions": { + "AccessToken": { + "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", + "type": "apiKey", + "name": "access_token", + "in": "query" + }, + "AuthorizationHeaderToken": { + "description": "API tokens must be prepended with \"token\" followed by a space.", + "type": "apiKey", + "name": "Authorization", + "in": "header" + }, + "BasicAuth": { + "type": "basic" + }, + "SudoHeader": { + "description": "Sudo API request as the user provided as the key. Admin privileges are required.", + "type": "apiKey", + "name": "Sudo", + "in": "header" + }, + "SudoParam": { + "description": "Sudo API request as the user provided as the key. Admin privileges are required.", + "type": "apiKey", + "name": "sudo", + "in": "query" + }, + "TOTPHeader": { + "description": "Must be used in combination with BasicAuth if two-factor authentication is enabled.", + "type": "apiKey", + "name": "X-FORGEJO-OTP", + "in": "header" + }, + "Token": { + "description": "This authentication option is deprecated for removal in Gitea 1.23. Please use AuthorizationHeaderToken instead.", + "type": "apiKey", + "name": "token", + "in": "query" + } + }, + "security": [ + { + "BasicAuth": [] + }, + { + "Token": [] + }, + { + "AccessToken": [] + }, + { + "AuthorizationHeaderToken": [] + }, + { + "SudoParam": [] + }, + { + "SudoHeader": [] + }, + { + "TOTPHeader": [] + } + ] +} diff --git a/tests/admin.rs b/tests/admin.rs new file mode 100644 index 0000000..38d47ba --- /dev/null +++ b/tests/admin.rs @@ -0,0 +1,194 @@ +use forgejo_api::structs::*; + +mod common; + +#[tokio::test] +async fn user() { + let api = common::login(); + + let user_opt = CreateUserOption { + created_at: None, + email: "pipis@noreply.example.org".into(), + full_name: None, + login_name: None, + must_change_password: None, + password: Some("userpass".into()), + restricted: Some(false), + send_notify: Some(true), + source_id: None, + username: "Pipis".into(), + visibility: Some("public".into()), + }; + let _ = api + .admin_create_user(user_opt) + .await + .expect("failed to create user"); + + let query = AdminSearchUsersQuery::default(); + let users = api + .admin_search_users(query) + .await + .expect("failed to search users"); + assert!( + users + .iter() + .find(|u| u.login.as_ref().unwrap() == "Pipis") + .is_some(), + "could not find new user" + ); + let query = AdminGetAllEmailsQuery::default(); + let users = api + .admin_get_all_emails(query) + .await + .expect("failed to search emails"); + assert!( + users + .iter() + .find(|u| u.email.as_ref().unwrap() == "pipis@noreply.example.org") + .is_some(), + "could not find new user" + ); +} + +#[tokio::test] +async fn org() { + let api = common::login(); + + let user_opt = CreateUserOption { + created_at: None, + email: "org-owner@noreply.example.org".into(), + full_name: None, + login_name: None, + must_change_password: None, + password: Some("userpass".into()), + restricted: Some(false), + send_notify: Some(true), + source_id: None, + username: "OrgOwner".into(), + visibility: Some("public".into()), + }; + let _ = api + .admin_create_user(user_opt) + .await + .expect("failed to create user"); + + let org_opt = CreateOrgOption { + description: None, + email: None, + full_name: None, + location: None, + repo_admin_change_team_access: None, + username: "test-org".into(), + visibility: Some(CreateOrgOptionVisibility::Public), + website: None, + }; + let _ = api + .admin_create_org("OrgOwner", org_opt) + .await + .expect("failed to create org"); + let query = AdminGetAllOrgsQuery::default(); + assert!( + !api.admin_get_all_orgs(query).await.unwrap().is_empty(), + "org list empty" + ); + let rename_opt = RenameUserOption { + new_username: "Bepis".into(), + }; + api.admin_rename_user("Pipis", rename_opt) + .await + .expect("failed to rename user"); + let query = AdminDeleteUserQuery { purge: Some(true) }; + api.admin_delete_user("Bepis", query) + .await + .expect("failed to delete user"); + let query = AdminDeleteUserQuery { purge: Some(true) }; + assert!( + api.admin_delete_user("Ghost", query).await.is_err(), + "deleting fake user should fail" + ); +} + +#[tokio::test] +async fn key() { + let api = common::login(); + + let user_opt = CreateUserOption { + created_at: None, + email: "key-holder@noreply.example.org".into(), + full_name: None, + login_name: None, + must_change_password: None, + password: Some("userpass".into()), + restricted: Some(false), + send_notify: Some(true), + source_id: None, + username: "KeyHolder".into(), + visibility: Some("public".into()), + }; + let _ = api + .admin_create_user(user_opt) + .await + .expect("failed to create user"); + + let key_opt = CreateKeyOption { + key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN68ehQAsbGEwlXPa2AxbAh1QxFQrtRel2jeC0hRlPc1 user@noreply.example.org".into(), + read_only: None, + title: "Example Key".into(), + }; + let key = api + .admin_create_public_key("KeyHolder", key_opt) + .await + .expect("failed to create key"); + api.admin_delete_user_public_key("KeyHolder", key.id.unwrap() as u64) + .await + .expect("failed to delete key"); +} + +#[tokio::test] +async fn cron() { + let api = common::login(); + + let query = AdminCronListQuery::default(); + let crons = api + .admin_cron_list(query) + .await + .expect("failed to get crons list"); + api.admin_cron_run(&crons.get(0).expect("no crons").name.as_ref().unwrap()) + .await + .expect("failed to run cron"); +} + +#[tokio::test] +async fn hook() { + let api = common::login(); + let hook_opt = CreateHookOption { + active: None, + authorization_header: None, + branch_filter: None, + config: CreateHookOptionConfig { + content_type: "json".into(), + url: url::Url::parse("http://test.local/").unwrap(), + additional: Default::default(), + }, + events: Some(Vec::new()), + r#type: CreateHookOptionType::Gitea, + }; + // yarr har har me matey this is me hook + let hook = api + .admin_create_hook(hook_opt) + .await + .expect("failed to create hook"); + let edit_hook = EditHookOption { + active: Some(true), + authorization_header: None, + branch_filter: None, + config: None, + events: None, + }; + api.admin_edit_hook(hook.id.unwrap() as u64, edit_hook) + .await + .expect("failed to edit hook"); + api.admin_delete_hook(hook.id.unwrap() as u64) + .await + .expect("failed to delete hook"); +} diff --git a/tests/common/mod.rs b/tests/common/mod.rs new file mode 100644 index 0000000..63ae02c --- /dev/null +++ b/tests/common/mod.rs @@ -0,0 +1,17 @@ +use forgejo_api::Forgejo; + +pub fn login() -> Forgejo { + let url = url::Url::parse(&std::env::var("FORGEJO_API_CI_INSTANCE_URL").unwrap()).unwrap(); + let token = std::env::var("FORGEJO_API_CI_TOKEN").unwrap(); + Forgejo::new(forgejo_api::Auth::Token(&token), url).unwrap() +} + +pub fn login_pass(username: &str, password: &str) -> Forgejo { + let url = url::Url::parse(&std::env::var("FORGEJO_API_CI_INSTANCE_URL").unwrap()).unwrap(); + let auth = forgejo_api::Auth::Password { + username, + password, + mfa: None, + }; + Forgejo::new(auth, url).unwrap() +} diff --git a/tests/organization.rs b/tests/organization.rs new file mode 100644 index 0000000..c5ced99 --- /dev/null +++ b/tests/organization.rs @@ -0,0 +1,58 @@ +use forgejo_api::structs::*; + +mod common; + +#[tokio::test] +async fn org_vars() { + let api = common::login(); + let org_opt = CreateOrgOption { + description: Some("Testing organization variables".into()), + email: None, + full_name: Some("Org Variables".into()), + location: Some("The Lab".into()), + repo_admin_change_team_access: None, + username: "org-vars".into(), + visibility: None, + website: None, + }; + api.org_create(org_opt).await.expect("failed to create org"); + + let query = GetOrgVariablesListQuery::default(); + let var_list = api + .get_org_variables_list("org-vars", query) + .await + .expect("failed to list org vars"); + assert!(var_list.is_empty()); + + let opt = CreateVariableOption { + value: "false".into(), + }; + api.create_org_variable("org-vars", "want_pizza", opt) + .await + .expect("failed to create org var"); + + let new_var = api + .get_org_variable("org-vars", "want_pizza") + .await + .expect("failed to get org var"); + assert_eq!(new_var.data.as_deref(), Some("false")); + + // no no no we definitely do want pizza + let opt = UpdateVariableOption { + name: Some("really_want_pizza".into()), + value: "true".into(), + }; + api.update_org_variable("org-vars", "want_pizza", opt) + .await + .expect("failed to update org variable"); + + let new_var = api + .get_org_variable("org-vars", "really_want_pizza") + .await + .expect("failed to get org var"); + assert_eq!(new_var.data.as_deref(), Some("true")); + + api.delete_org_variable("org-vars", "really_want_pizza") + .await + .expect("failed to delete org var"); +} diff --git a/tests/repo.rs b/tests/repo.rs new file mode 100644 index 0000000..3a0377c --- /dev/null +++ b/tests/repo.rs @@ -0,0 +1,495 @@ +use forgejo_api::structs::*; + +mod common; + +struct Git { + dir: &'static std::path::Path, +} + +impl Git { + fn new<T: AsRef<std::path::Path> + ?Sized>(path: &'static T) -> Self { + let dir = path.as_ref(); + std::fs::create_dir_all(dir).unwrap(); + Self { dir } + } + + fn run(&self, args: &[impl AsRef<std::ffi::OsStr>]) { + let mut cmd = std::process::Command::new("git"); + cmd.current_dir(self.dir); + let _ = cmd.args(args).status().unwrap(); + } +} + +async fn setup_local_repo(git: &Git) { + git.run(&["config", "--global", "init.defaultBranch", "main"]); + git.run(&["init"]); + git.run(&["config", "user.name", "TestingAdmin"]); + git.run(&["config", "user.email", "admin@noreply.example.org"]); + tokio::fs::write(&git.dir.join("README.md"), "# Test\nThis is a test repo") + .await + .unwrap(); + git.run(&["add", "."]); + git.run(&["commit", "-m", "initial commit"]); +} + +async fn basic_repo(api: &forgejo_api::Forgejo, git: &Git, name: &str) -> Repository { + setup_local_repo(git).await; + let repo_opt = CreateRepoOption { + auto_init: Some(false), + default_branch: Some("main".into()), + description: Some("Test Repo".into()), + gitignores: Some("".into()), + issue_labels: Some("".into()), + license: Some("".into()), + name: name.into(), + object_format_name: None, + private: Some(false), + readme: None, + template: Some(false), + trust_model: Some(CreateRepoOptionTrustModel::Default), + }; + let remote_repo = api.create_current_user_repo(repo_opt).await.unwrap(); + assert!( + remote_repo.has_pull_requests.unwrap(), + "repo does not accept pull requests" + ); + assert!( + remote_repo.owner.as_ref().unwrap().login.as_ref().unwrap() == "TestingAdmin", + "repo owner is not \"TestingAdmin\"" + ); + assert!( + remote_repo.name.as_ref().unwrap() == name, + "repo name is not \"{name}\"" + ); + + let mut remote_url = remote_repo.clone_url.clone().unwrap(); + remote_url.set_username("TestingAdmin").unwrap(); + remote_url.set_password(Some("password")).unwrap(); + git.run(&["remote", "add", "origin", remote_url.as_str()]); + git.run(&["push", "-u", "origin", "main"]); + + remote_repo +} + +async fn basic_org_repo( + api: &forgejo_api::Forgejo, + git: &Git, + org: &str, + name: &str, +) -> Repository { + setup_local_repo(git).await; + + let repo_opt = CreateRepoOption { + auto_init: Some(false), + default_branch: Some("main".into()), + description: Some("Test Repo".into()), + gitignores: Some("".into()), + issue_labels: Some("".into()), + license: Some("".into()), + name: name.into(), + object_format_name: None, + private: Some(false), + readme: None, + template: Some(false), + trust_model: Some(CreateRepoOptionTrustModel::Default), + }; + let remote_repo = api.create_org_repo(org, repo_opt).await.unwrap(); + assert!( + remote_repo.has_pull_requests.unwrap(), + "repo does not accept pull requests" + ); + assert!( + remote_repo.owner.as_ref().unwrap().login.as_ref().unwrap() == org, + "repo owner is not \"TestingAdmin\"" + ); + assert!( + remote_repo.name.as_ref().unwrap() == name, + "repo name is not \"{name}\"" + ); + + let mut remote_url = remote_repo.clone_url.clone().unwrap(); + remote_url.set_username("TestingAdmin").unwrap(); + remote_url.set_password(Some("password")).unwrap(); + git.run(&["remote", "add", "origin", remote_url.as_str()]); + git.run(&["push", "-u", "origin", "main"]); + + remote_repo +} + +#[tokio::test] +async fn pull_request() { + let api = common::login(); + + let git = Git::new("./test_repos/pr"); + let _ = basic_repo(&api, &git, "pr-test").await; + git.run(&["switch", "-c", "test"]); + + tokio::fs::write( + "./test_repos/pr/example.rs", + "fn add_one(x: u32) -> u32 { x + 1 }", + ) + .await + .unwrap(); + git.run(&["add", "."]); + git.run(&["commit", "-m", "egg"]); + git.run(&["push", "-u", "origin", "test"]); + + let pr_opt = CreatePullRequestOption { + assignee: None, + assignees: Some(vec!["TestingAdmin".into()]), + base: Some("main".into()), + body: Some("This is a test PR".into()), + due_date: None, + head: Some("test".into()), + labels: None, + milestone: None, + title: Some("test pr".into()), + }; + + // Wait for... something to happen, or else creating a PR will return 404 + tokio::time::sleep(std::time::Duration::from_secs(3)).await; + let pr = api + .repo_create_pull_request("TestingAdmin", "pr-test", pr_opt) + .await + .expect("couldn't create pr"); + + let is_merged = api + .repo_pull_request_is_merged("TestingAdmin", "pr-test", pr.number.unwrap() as u64) + .await + .is_ok(); + assert!(!is_merged, "pr should not yet be merged"); + + let pr_files_query = RepoGetPullRequestFilesQuery::default(); + let (_, _) = api + .repo_get_pull_request_files( + "TestingAdmin", + "pr-test", + pr.number.unwrap() as u64, + pr_files_query, + ) + .await + .unwrap(); + + let merge_opt = MergePullRequestOption { + r#do: MergePullRequestOptionDo::Merge, + merge_commit_id: None, + merge_message_field: None, + merge_title_field: None, + delete_branch_after_merge: Some(true), + force_merge: None, + head_commit_id: None, + merge_when_checks_succeed: None, + }; + + api.repo_merge_pull_request( + "TestingAdmin", + "pr-test", + pr.number.unwrap() as u64, + merge_opt, + ) + .await + .expect("couldn't merge pr"); + let is_merged = api + .repo_pull_request_is_merged("TestingAdmin", "pr-test", pr.number.unwrap() as u64) + .await + .is_ok(); + assert!(is_merged, "pr should be merged"); +} + +#[tokio::test] +async fn release() { + let api = common::login(); + + let git = Git::new("./test_repos/release"); + let _ = basic_repo(&api, &git, "release-test").await; + + // Wait for the repo to be finished being populated, or else creating a + // release will return "422 repo is empty" + tokio::time::sleep(std::time::Duration::from_secs(3)).await; + + let query = RepoListReleasesQuery::default(); + assert!( + api.repo_list_releases("TestingAdmin", "release-test", query) + .await + .unwrap() + .is_empty(), + "there should be no releases yet" + ); + + let tag_opt = CreateTagOption { + message: Some("This is a tag!".into()), + tag_name: "v1.0".into(), + target: None, + }; + api.repo_create_tag("TestingAdmin", "release-test", tag_opt) + .await + .expect("failed to create tag"); + + let release_opt = CreateReleaseOption { + body: Some("This is a release!".into()), + draft: Some(true), + name: Some("v1.0".into()), + prerelease: Some(false), + tag_name: "v1.0".into(), + target_commitish: None, + hide_archive_links: None, + }; + let release = api + .repo_create_release("TestingAdmin", "release-test", release_opt) + .await + .expect("failed to create release"); + let edit_release = EditReleaseOption { + body: None, + draft: Some(false), + name: None, + prerelease: None, + tag_name: None, + target_commitish: None, + hide_archive_links: None, + }; + api.repo_edit_release( + "TestingAdmin", + "release-test", + release.id.unwrap() as u64, + edit_release, + ) + .await + .expect("failed to edit release"); + + let release_by_tag = api + .repo_get_release_by_tag("TestingAdmin", "release-test", "v1.0") + .await + .expect("failed to find release"); + let release_latest = api + .repo_get_latest_release("TestingAdmin", "release-test") + .await + .expect("failed to find latest release"); + assert!(release_by_tag == release_latest, "releases not equal"); + + let attachment = api + .repo_create_release_attachment( + "TestingAdmin", + "release-test", + release.id.unwrap() as u64, + b"This is a file!".to_vec(), + RepoCreateReleaseAttachmentQuery { + name: Some("test.txt".into()), + }, + ) + .await + .expect("failed to create release attachment"); + assert!( + &*api + .download_release_attachment( + "TestingAdmin", + "release-test", + release.id.unwrap() as u64, + attachment.id.unwrap() as u64 + ) + .await + .unwrap() + == b"This is a file!", + "couldn't download attachment" + ); + let _zip_archive = api + .repo_get_archive("TestingAdmin", "release-test", "v1.0.zip") + .await + .unwrap(); + let _tar_archive = api + .repo_get_archive("TestingAdmin", "release-test", "v1.0.tar.gz") + .await + .unwrap(); + // check these contents when their return value is fixed + + api.repo_delete_release_attachment( + "TestingAdmin", + "release-test", + release.id.unwrap() as u64, + attachment.id.unwrap() as u64, + ) + .await + .expect("failed to deleted attachment"); + + api.repo_delete_release("TestingAdmin", "release-test", release.id.unwrap() as u64) + .await + .expect("failed to delete release"); + + api.repo_delete_tag("TestingAdmin", "release-test", "v1.0") + .await + .expect("failed to delete release"); +} + +#[tokio::test] +async fn delete_repo() { + let api = common::login(); + let git = Git::new("./test_repos/delete"); + let _ = basic_repo(&api, &git, "delete-test").await; + + api.repo_delete("TestingAdmin", "delete-test") + .await + .expect("failed to delete repo"); +} + +#[tokio::test] +async fn team_pr_review_request() { + let api = common::login(); + + let org_opt = CreateOrgOption { + description: Some("Testing team review requests".into()), + email: None, + full_name: None, + location: None, + repo_admin_change_team_access: None, + username: "team-review-org".into(), + visibility: None, + website: None, + }; + api.org_create(org_opt).await.unwrap(); + + let git = Git::new("./test_repos/team-pr-review"); + let _ = basic_org_repo(&api, &git, "team-review-org", "team-pr-review").await; + + git.run(&["switch", "-c", "test"]); + tokio::fs::write( + "./test_repos/team-pr-review/example.rs", + "fn add_one(x: u32) -> u32 { x + 1 }", + ) + .await + .unwrap(); + git.run(&["add", "."]); + git.run(&["commit", "-m", "egg"]); + git.run(&["push", "-u", "origin", "test"]); + + let pr_opt = CreatePullRequestOption { + assignee: None, + assignees: Some(vec!["TestingAdmin".into()]), + base: Some("main".into()), + body: Some("This is a test PR".into()), + due_date: None, + head: Some("test".into()), + labels: None, + milestone: None, + title: Some("test pr".into()), + }; + + // Wait for... something to happen, or else creating a PR will return 404 + tokio::time::sleep(std::time::Duration::from_secs(3)).await; + api.repo_create_pull_request("team-review-org", "team-pr-review", pr_opt) + .await + .expect("couldn't create pr"); + + let review_opt = PullReviewRequestOptions { + reviewers: None, + team_reviewers: Some(vec!["Owners".into()]), + }; + api.repo_create_pull_review_requests("team-review-org", "team-pr-review", 1, review_opt) + .await + .expect("couldn't request review"); + + let pr = api + .repo_get_pull_request("team-review-org", "team-pr-review", 1) + .await + .expect("couldn't get pr"); + assert_eq!(pr.requested_reviewers, Some(Vec::new())); +} + +#[tokio::test] +async fn tag_protection() { + let api = common::login(); + let git = Git::new("./test_repos/tag-protect"); + let _ = basic_repo(&api, &git, "tag-protect").await; + + let tag_protections = api + .repo_list_tag_protection("TestingAdmin", "tag-protect") + .await + .expect("failed to list tag protections"); + assert!(tag_protections.is_empty()); + + let protection_opt = CreateTagProtectionOption { + name_pattern: Some("v*".into()), + whitelist_teams: None, + whitelist_usernames: Some(vec!["TestingAdmin".into()]), + }; + let new_protection = api + .repo_create_tag_protection("TestingAdmin", "tag-protect", protection_opt) + .await + .expect("failed to create tag protection"); + let pattern = new_protection + .name_pattern + .as_deref() + .expect("protection does not have pattern"); + assert_eq!(pattern, "v*"); + let id = new_protection.id.expect("protection does not have id") as u32; + + let protection_get = api + .repo_get_tag_protection("TestingAdmin", "tag-protect", id) + .await + .expect("failed to get tag protection"); + assert_eq!(new_protection, protection_get); + + let edit_opt = EditTagProtectionOption { + name_pattern: Some("v*.*.*".into()), + whitelist_teams: None, + whitelist_usernames: Some(vec![]), + }; + let edited = api + .repo_edit_tag_protection("TestingAdmin", "tag-protect", id, edit_opt) + .await + .expect("failed to edit tag protection"); + let pattern = edited + .name_pattern + .as_deref() + .expect("protection does not have pattern"); + assert_eq!(pattern, "v*.*.*"); + + api.repo_delete_tag_protection("TestingAdmin", "tag-protect", id) + .await + .expect("failed to delete tag protection"); +} + +#[tokio::test] +async fn repo_vars() { + let api = common::login(); + let git = Git::new("./test_repos/repo-vars"); + let _ = basic_repo(&api, &git, "repo-vars").await; + + let query = GetRepoVariablesListQuery::default(); + let var_list = api + .get_repo_variables_list("TestingAdmin", "repo-vars", query) + .await + .expect("failed to list repo vars"); + assert!(var_list.is_empty()); + + let opt = CreateVariableOption { + value: "false".into(), + }; + api.create_repo_variable("TestingAdmin", "repo-vars", "very_cool", opt) + .await + .expect("failed to create repo var"); + + let new_var = api + .get_repo_variable("TestingAdmin", "repo-vars", "very_cool") + .await + .expect("failed to get repo var"); + assert_eq!(new_var.data.as_deref(), Some("false")); + + // wait, that's not right. you ARE very cool! + // gotta fix that + let opt = UpdateVariableOption { + name: Some("extremely_cool".into()), + value: "true".into(), + }; + api.update_repo_variable("TestingAdmin", "repo-vars", "very_cool", opt) + .await + .expect("failed to update repo variable"); + + let new_var = api + .get_repo_variable("TestingAdmin", "repo-vars", "extremely_cool") + .await + .expect("failed to get repo var"); + assert_eq!(new_var.data.as_deref(), Some("true")); + + api.delete_repo_variable("TestingAdmin", "repo-vars", "extremely_cool") + .await + .expect("failed to delete repo var"); +} diff --git a/tests/user.rs b/tests/user.rs new file mode 100644 index 0000000..3b6e0e3 --- /dev/null +++ b/tests/user.rs @@ -0,0 +1,237 @@ +use forgejo_api::structs::*; + +mod common; + +#[tokio::test] +async fn myself() { + let api = common::login(); + + let myself = api.user_get_current().await.unwrap(); + assert!(myself.is_admin.unwrap(), "user should be admin"); + assert_eq!( + myself.login.as_ref().unwrap(), + "TestingAdmin", + "user should be named \"TestingAdmin\"" + ); + + let myself_indirect = api.user_get("TestingAdmin").await.unwrap(); + assert_eq!( + myself, myself_indirect, + "result of `myself` does not match result of `get_user`" + ); +} + +#[tokio::test] +async fn follow() { + let api = common::login(); + + let query = UserListFollowingQuery::default(); + let following = api + .user_list_following("TestingAdmin", query) + .await + .unwrap(); + assert!(following.is_empty(), "following list not empty"); + + let query = UserListFollowersQuery::default(); + let followers = api + .user_list_followers("TestingAdmin", query) + .await + .unwrap(); + assert!(followers.is_empty(), "follower list not empty"); + + let option = CreateUserOption { + created_at: None, + email: "follower@no-reply.example.org".into(), + full_name: None, + login_name: None, + must_change_password: Some(false), + password: Some("password".into()), + restricted: None, + send_notify: None, + source_id: None, + username: "Follower".into(), + visibility: None, + }; + let _ = api.admin_create_user(option).await.unwrap(); + let new_user = common::login_pass("Follower", "password"); + + new_user + .user_current_put_follow("TestingAdmin") + .await + .unwrap(); + api.user_current_put_follow("Follower").await.unwrap(); + + let query = UserListFollowingQuery::default(); + let following = api + .user_list_following("TestingAdmin", query) + .await + .unwrap(); + assert!(!following.is_empty(), "following list empty"); + + let query = UserListFollowersQuery::default(); + let followers = api + .user_list_followers("TestingAdmin", query) + .await + .unwrap(); + assert!(!followers.is_empty(), "follower list empty"); +} + +#[tokio::test] +async fn password_login() { + let api = common::login(); + let password_api = common::login_pass("TestingAdmin", "password"); + + assert!( + api.user_get_current().await.unwrap() == password_api.user_get_current().await.unwrap(), + "users not equal comparing token-auth and pass-auth" + ); +} + +#[tokio::test] +async fn oauth2_login() { + let api = common::login(); + let opt = forgejo_api::structs::CreateOAuth2ApplicationOptions { + confidential_client: Some(true), + name: Some("Test Application".into()), + redirect_uris: Some(vec!["http://127.0.0.1:48879/".into()]), + }; + let app = api.user_create_oauth2_application(opt).await.unwrap(); + let client_id = app.client_id.unwrap(); + let client_secret = app.client_secret.unwrap(); + + let base_url = &std::env::var("FORGEJO_API_CI_INSTANCE_URL").unwrap(); + + let client = reqwest::Client::builder() + .cookie_store(true) + .redirect(reqwest::redirect::Policy::none()) + .build() + .unwrap(); + + // Log in via the web interface + let _ = client + .post(&format!("{base_url}user/login")) + .form(&[("user_name", "TestingAdmin"), ("password", "password")]) + .send() + .await + .unwrap() + .error_for_status() + .unwrap(); + + // Load the authorization page + let response = client + .get(&format!( + "{base_url}login/oauth/authorize\ + ?client_id={client_id}\ + &redirect_uri=http%3A%2F%2F127.0.0.1%3A48879%2F\ + &response_type=code\ + &state=theyve" + )) + .send() + .await + .unwrap() + .error_for_status() + .unwrap(); + let csrf = response.cookies().find(|x| x.name() == "_csrf").unwrap(); + + // Authorize the new application via the web interface + let response = client + .post(&format!("{base_url}login/oauth/grant")) + .form(&[ + ("_csrf", csrf.value()), + ("client_id", &client_id), + ("state", "theyve"), + ("scope", ""), + ("nonce", ""), + ("redirect_uri", "http://127.0.0.1:48879/"), + ]) + .send() + .await + .unwrap() + .error_for_status() + .unwrap(); + + // Extract the code from the redirect url + let location = response.headers().get(reqwest::header::LOCATION).unwrap(); + let location = url::Url::parse(dbg!(location.to_str().unwrap())).unwrap(); + let mut code = None; + for (key, value) in location.query_pairs() { + if key == "code" { + code = Some(value.into_owned()); + } else if key == "error_description" { + panic!("{value}"); + } + } + let code = code.unwrap(); + + // Redeem the code and check it works + let url = url::Url::parse(&base_url).unwrap(); + let api = forgejo_api::Forgejo::new(forgejo_api::Auth::None, url.clone()).unwrap(); + + let request = forgejo_api::structs::OAuthTokenRequest::Confidential { + client_id: &client_id, + client_secret: &client_secret, + code: &code, + redirect_uri: url::Url::parse("http://127.0.0.1:48879/").unwrap(), + }; + let token = api.oauth_get_access_token(request).await.unwrap(); + let token_api = + forgejo_api::Forgejo::new(forgejo_api::Auth::OAuth2(&token.access_token), url.clone()) + .unwrap(); + let myself = token_api.user_get_current().await.unwrap(); + assert_eq!(myself.login.as_deref(), Some("TestingAdmin")); + + let request = forgejo_api::structs::OAuthTokenRequest::Refresh { + refresh_token: &token.refresh_token, + client_id: &client_id, + client_secret: &client_secret, + }; + let token = token_api.oauth_get_access_token(request).await.unwrap(); + let token_api = + forgejo_api::Forgejo::new(forgejo_api::Auth::OAuth2(&token.access_token), url).unwrap(); + let myself = token_api.user_get_current().await.unwrap(); + assert_eq!(myself.login.as_deref(), Some("TestingAdmin")); +} + +#[tokio::test] +async fn user_vars() { + let api = common::login(); + + let query = GetUserVariablesListQuery::default(); + let var_list = api + .get_user_variables_list(query) + .await + .expect("failed to list user vars"); + assert!(var_list.is_empty()); + + let opt = CreateVariableOption { + value: "false".into(), + }; + api.create_user_variable("likes_dogs", opt) + .await + .expect("failed to create user var"); + + let new_var = api + .get_user_variable("likes_dogs") + .await + .expect("failed to get user var"); + assert_eq!(new_var.data.as_deref(), Some("false")); + + // what??? totally wrong. I love dogs! + let opt = UpdateVariableOption { + name: Some("loves_dogs".into()), + value: "true".into(), + }; + api.update_user_variable("likes_dogs", opt) + .await + .expect("failed to update user variable"); + + let new_var = api + .get_user_variable("loves_dogs") + .await + .expect("failed to get user var"); + assert_eq!(new_var.data.as_deref(), Some("true")); + + api.delete_user_variable("loves_dogs") + .await + .expect("failed to delete user var"); +} |