summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCyborus <cyborus@noreply.codeberg.org>2024-10-23 20:53:11 +0200
committerCyborus <cyborus@noreply.codeberg.org>2024-10-23 20:53:11 +0200
commit2539731dd8197055ce6176ccbc4a1bf77e7bc79e (patch)
tree0de68f13331a2a2a27f9b634c1f6a9c400f9d06f
parentMerge pull request 'Clippy Fixes' (#74) from Pi-Cla/forgejo-api:clippy into main (diff)
parentci: update ci forgejo to 9.0 (diff)
downloadforgejo-api-main.tar.xz
forgejo-api-main.zip
Merge pull request 'update to forgejo 9' (#75) from forgejo-9 into mainHEADmain
Reviewed-on: https://codeberg.org/Cyborus/forgejo-api/pulls/75
-rw-r--r--.woodpecker/integration.yml4
-rw-r--r--generator/src/methods.rs31
-rw-r--r--src/generated/methods.rs557
-rw-r--r--src/generated/structs.rs403
-rw-r--r--swagger.v1.json1545
-rw-r--r--tests/admin.rs88
-rw-r--r--tests/repo.rs5
7 files changed, 2528 insertions, 105 deletions
diff --git a/.woodpecker/integration.yml b/.woodpecker/integration.yml
index 8dd4e3e..9e100cd 100644
--- a/.woodpecker/integration.yml
+++ b/.woodpecker/integration.yml
@@ -5,11 +5,11 @@ steps:
image: rust
environment:
- "FORGEJO_API_CI_INSTANCE_URL=http://forgejo-testing:3000/"
- - FORGEJO_API_CI_TOKEN=e4f301dffd4993a3389f601761c0103291e58d85
+ - FORGEJO_API_CI_TOKEN=6eaba97c49d9f1bbe54f8975ea884af54826c9fe
commands:
- cargo test
services:
forgejo-testing:
pull: true
- image: code.cartoon-aa.xyz/cyborus/ci-forgejo:8.0.0
+ image: code.cartoon-aa.xyz/cyborus/ci-forgejo:9.0.0
diff --git a/generator/src/methods.rs b/generator/src/methods.rs
index 141fc7d..ffed912 100644
--- a/generator/src/methods.rs
+++ b/generator/src/methods.rs
@@ -174,10 +174,14 @@ fn fn_args_from_op(spec: &OpenApiV2, op: &Operation) -> eyre::Result<String> {
args.push_str(": ");
args.push_str(&ty);
}
- ParameterIn::FormData { param: _ } => {
+ ParameterIn::FormData { param } => {
args.push_str(", ");
args.push_str(&crate::sanitize_ident(&full_param.name));
- args.push_str(": Vec<u8>");
+ if param.required {
+ args.push_str(": Vec<u8>");
+ } else {
+ args.push_str(": Option<Vec<u8>>");
+ }
}
}
}
@@ -360,6 +364,7 @@ fn create_method_request(
let mut has_query = false;
// let mut has_headers = false;
let mut body_method = String::new();
+ let mut form_methods = String::new();
if let Some(params) = &op.parameters {
for param in params {
let param = param.deref(spec)?;
@@ -378,11 +383,15 @@ fn create_method_request(
body_method = format!(".json(&{name})");
}
}
- ParameterIn::FormData { param: _ } => {
- if !body_method.is_empty() {
- eyre::bail!("cannot have more than one body parameter");
+ ParameterIn::FormData { param } => {
+ if param.required {
+ form_methods += &format!("let builder = builder.multipart(reqwest::multipart::Form::new().part(\"attachment\", reqwest::multipart::Part::bytes({name}).file_name(\"file\").mime_str(\"*/*\").unwrap()));");
+ } else {
+ form_methods += &format!("let builder = match {name} {{
+ Some({name}) => builder.multipart(reqwest::multipart::Form::new().part(\"attachment\", reqwest::multipart::Part::bytes({name}).file_name(\"file\").mime_str(\"*/*\").unwrap())),
+ None => builder,
+ }};");
}
- body_method = format!(".multipart(reqwest::multipart::Form::new().part(\"attachment\", reqwest::multipart::Part::bytes({name}).file_name(\"file\").mime_str(\"*/*\").unwrap()))");
}
}
}
@@ -397,7 +406,15 @@ fn create_method_request(
format!("\"{fmt_str}\"")
};
- let out = format!("let request = self.{method}({path_arg}){body_method}.build()?;");
+ let out = if form_methods.is_empty() {
+ format!("let request = self.{method}({path_arg}){body_method}.build()?;")
+ } else {
+ format!(
+ "let builder = self.{method}({path_arg}){body_method};
+ {form_methods}\
+ let request = builder.build()?;"
+ )
+ };
Ok(out)
}
diff --git a/src/generated/methods.rs b/src/generated/methods.rs
index 2b23abf..f49d61f 100644
--- a/src/generated/methods.rs
+++ b/src/generated/methods.rs
@@ -3,6 +3,26 @@ use crate::ForgejoError;
use std::collections::BTreeMap;
impl crate::Forgejo {
+ /// Returns the instance's Actor
+ pub async fn activitypub_instance_actor(&self) -> Result<ActivityPub, ForgejoError> {
+ let request = self.get("activitypub/actor").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
+ pub async fn activitypub_instance_actor_inbox(&self) -> Result<(), ForgejoError> {
+ let request = self.post("activitypub/actor/inbox").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
/// Returns the Repository actor for a repo
///
/// - `repository-id`: repository ID of the repo
@@ -206,6 +226,239 @@ impl crate::Forgejo {
}
}
+ /// List the available quota groups
+ pub async fn admin_list_quota_groups(&self) -> Result<Vec<QuotaGroup>, ForgejoError> {
+ let request = self.get("admin/quota/groups").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 quota group
+ ///
+ /// - `group`: Definition of the quota group
+
+ /// See [`CreateQuotaGroupOptions`]
+ pub async fn admin_create_quota_group(
+ &self,
+ group: CreateQuotaGroupOptions,
+ ) -> Result<QuotaGroup, ForgejoError> {
+ let request = self.post("admin/quota/groups").json(&group).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get information about the quota group
+ ///
+ /// - `quotagroup`: quota group to query
+ pub async fn admin_get_quota_group(
+ &self,
+ quotagroup: &str,
+ ) -> Result<QuotaGroup, ForgejoError> {
+ let request = self
+ .get(&format!("admin/quota/groups/{quotagroup}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a quota group
+ ///
+ /// - `quotagroup`: quota group to delete
+ pub async fn admin_delete_quota_group(&self, quotagroup: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/quota/groups/{quotagroup}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Adds a rule to a quota group
+ ///
+ /// - `quotagroup`: quota group to add a rule to
+ /// - `quotarule`: the name of the quota rule to add to the group
+ pub async fn admin_add_rule_to_quota_group(
+ &self,
+ quotagroup: &str,
+ quotarule: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!(
+ "admin/quota/groups/{quotagroup}/rules/{quotarule}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Removes a rule from a quota group
+ ///
+ /// - `quotagroup`: quota group to remove a rule from
+ /// - `quotarule`: the name of the quota rule to remove from the group
+ pub async fn admin_remove_rule_from_quota_group(
+ &self,
+ quotagroup: &str,
+ quotarule: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "admin/quota/groups/{quotagroup}/rules/{quotarule}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List users in a quota group
+ ///
+ /// - `quotagroup`: quota group to list members of
+ pub async fn admin_list_users_in_quota_group(
+ &self,
+ quotagroup: &str,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("admin/quota/groups/{quotagroup}/users"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a user to a quota group
+ ///
+ /// - `quotagroup`: quota group to add the user to
+ /// - `username`: username of the user to add to the quota group
+ pub async fn admin_add_user_to_quota_group(
+ &self,
+ quotagroup: &str,
+ username: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("admin/quota/groups/{quotagroup}/users/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a user from a quota group
+ ///
+ /// - `quotagroup`: quota group to remove a user from
+ /// - `username`: username of the user to remove from the quota group
+ pub async fn admin_remove_user_from_quota_group(
+ &self,
+ quotagroup: &str,
+ username: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/quota/groups/{quotagroup}/users/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the available quota rules
+ pub async fn admin_list_quota_rules(&self) -> Result<Vec<QuotaRuleInfo>, ForgejoError> {
+ let request = self.get("admin/quota/rules").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 quota rule
+ ///
+ /// - `rule`: Definition of the quota rule
+
+ /// See [`CreateQuotaRuleOptions`]
+ pub async fn admin_create_quota_rule(
+ &self,
+ rule: CreateQuotaRuleOptions,
+ ) -> Result<QuotaRuleInfo, ForgejoError> {
+ let request = self.post("admin/quota/rules").json(&rule).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get information about a quota rule
+ ///
+ /// - `quotarule`: quota rule to query
+ pub async fn admin_get_quota_rule(
+ &self,
+ quotarule: &str,
+ ) -> Result<QuotaRuleInfo, ForgejoError> {
+ let request = self
+ .get(&format!("admin/quota/rules/{quotarule}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Deletes a quota rule
+ ///
+ /// - `quotarule`: quota rule to delete
+ pub async fn admin_delete_quota_rule(&self, quotarule: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/quota/rules/{quotarule}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Change an existing quota rule
+ ///
+ /// - `quotarule`: Quota rule to change
+ /// - `rule`: See [`EditQuotaRuleOptions`]
+ pub async fn admin_edit_quota_rule(
+ &self,
+ quotarule: &str,
+ rule: EditQuotaRuleOptions,
+ ) -> Result<QuotaRuleInfo, ForgejoError> {
+ let request = self
+ .patch(&format!("admin/quota/rules/{quotarule}"))
+ .json(&rule)
+ .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,
@@ -393,6 +646,40 @@ impl crate::Forgejo {
}
}
+ /// Get the user's quota info
+ ///
+ /// - `username`: username of user to query
+ pub async fn admin_get_user_quota(&self, username: &str) -> Result<QuotaInfo, ForgejoError> {
+ let request = self.get(&format!("admin/users/{username}/quota")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Set the user's quota groups to a given list.
+ ///
+ /// - `username`: username of the user to modify the quota groups from
+ /// - `groups`: list of groups that the user should be a member of
+
+ /// See [`SetUserQuotaGroupsOptions`]
+ pub async fn admin_set_user_quota_groups(
+ &self,
+ username: &str,
+ groups: SetUserQuotaGroupsOptions,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("admin/users/{username}/quota/groups"))
+ .json(&groups)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
/// Rename a user
///
/// - `username`: existing username of user
@@ -1256,6 +1543,84 @@ impl crate::Forgejo {
}
}
+ /// Get quota information for an organization
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_get_quota(&self, org: &str) -> Result<QuotaInfo, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/quota")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the artifacts affecting the organization's quota
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_quota_artifacts(
+ &self,
+ org: &str,
+ query: OrgListQuotaArtifactsQuery,
+ ) -> Result<Vec<QuotaUsedArtifact>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/quota/artifacts?{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 attachments affecting the organization's quota
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_quota_attachments(
+ &self,
+ org: &str,
+ query: OrgListQuotaAttachmentsQuery,
+ ) -> Result<Vec<QuotaUsedAttachment>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/quota/attachments?{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 organization is over quota for a given subject
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_check_quota(&self, org: &str) -> Result<(), ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/quota/check")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the packages affecting the organization's quota
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_quota_packages(
+ &self,
+ org: &str,
+ query: OrgListQuotaPackagesQuery,
+ ) -> Result<Vec<QuotaUsedPackage>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/quota/packages?{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 repos
///
/// - `org`: name of the organization
@@ -1533,6 +1898,27 @@ impl crate::Forgejo {
}
}
+ /// 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}/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 repo's actions secrets
///
/// - `owner`: owner of the repository
@@ -3235,20 +3621,19 @@ impl crate::Forgejo {
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 builder = self.post(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/assets?{query}"
+ ));
+ let builder = builder.multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(attachment)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ );
+ let request = builder.build()?;
let response = self.execute(request).await?;
match response.status().as_u16() {
201 => Ok(response.json().await?),
@@ -3530,20 +3915,19 @@ impl crate::Forgejo {
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 builder = self.post(&format!(
+ "repos/{owner}/{repo}/issues/{index}/assets?{query}"
+ ));
+ let builder = builder.multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(attachment)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ );
+ let request = builder.build()?;
let response = self.execute(request).await?;
match response.status().as_u16() {
201 => Ok(response.json().await?),
@@ -5791,20 +6175,22 @@ impl crate::Forgejo {
/// - `owner`: owner of the repo
/// - `repo`: name of the repo
/// - `id`: id of the release
- /// - `attachment`: attachment to upload
+ /// - `attachment`: attachment to upload (this parameter is incompatible with `external_url`)
+ /// - `external_url`: url to external asset (this parameter is incompatible with `attachment`)
pub async fn repo_create_release_attachment(
&self,
owner: &str,
repo: &str,
id: u64,
- attachment: Vec<u8>,
+ attachment: Option<Vec<u8>>,
+ external_url: Option<Vec<u8>>,
query: RepoCreateReleaseAttachmentQuery,
) -> Result<Attachment, ForgejoError> {
- let request = self
- .post(&format!(
- "repos/{owner}/{repo}/releases/{id}/assets?{query}"
- ))
- .multipart(
+ let builder = self.post(&format!(
+ "repos/{owner}/{repo}/releases/{id}/assets?{query}"
+ ));
+ let builder = match attachment {
+ Some(attachment) => builder.multipart(
reqwest::multipart::Form::new().part(
"attachment",
reqwest::multipart::Part::bytes(attachment)
@@ -5812,8 +6198,22 @@ impl crate::Forgejo {
.mime_str("*/*")
.unwrap(),
),
- )
- .build()?;
+ ),
+ None => builder,
+ };
+ let builder = match external_url {
+ Some(external_url) => builder.multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(external_url)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ ),
+ None => builder,
+ };
+ let request = builder.build()?;
let response = self.execute(request).await?;
match response.status().as_u16() {
201 => Ok(response.json().await?),
@@ -5918,25 +6318,6 @@ impl crate::Forgejo {
}
}
- /// 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
@@ -7583,6 +7964,70 @@ impl crate::Forgejo {
}
}
+ /// Get quota information for the authenticated user
+ pub async fn user_get_quota(&self) -> Result<QuotaInfo, ForgejoError> {
+ let request = self.get("user/quota").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the artifacts affecting the authenticated user's quota
+ ///
+ pub async fn user_list_quota_artifacts(
+ &self,
+ query: UserListQuotaArtifactsQuery,
+ ) -> Result<Vec<QuotaUsedArtifact>, ForgejoError> {
+ let request = self.get(&format!("user/quota/artifacts?{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 attachments affecting the authenticated user's quota
+ ///
+ pub async fn user_list_quota_attachments(
+ &self,
+ query: UserListQuotaAttachmentsQuery,
+ ) -> Result<Vec<QuotaUsedAttachment>, ForgejoError> {
+ let request = self
+ .get(&format!("user/quota/attachments?{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 authenticated user is over quota for a given subject
+ pub async fn user_check_quota(&self) -> Result<(), ForgejoError> {
+ let request = self.get("user/quota/check").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the packages affecting the authenticated user's quota
+ ///
+ pub async fn user_list_quota_packages(
+ &self,
+ query: UserListQuotaPackagesQuery,
+ ) -> Result<Vec<QuotaUsedPackage>, ForgejoError> {
+ let request = self.get(&format!("user/quota/packages?{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(
diff --git a/src/generated/structs.rs b/src/generated/structs.rs
index b99c2a0..a65f45d 100644
--- a/src/generated/structs.rs
+++ b/src/generated/structs.rs
@@ -147,9 +147,18 @@ pub struct ActivityPub {
/// 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>,
+ pub permission: Option<AddCollaboratorOptionPermission>,
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+pub enum AddCollaboratorOptionPermission {
+ #[serde(rename = "read")]
+ Read,
+ #[serde(rename = "write")]
+ Write,
+ #[serde(rename = "admin")]
+ Admin,
+}
/// AddTimeOption options for adding time to an issue
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct AddTimeOption {
@@ -196,9 +205,18 @@ pub struct Attachment {
pub id: Option<i64>,
pub name: Option<String>,
pub size: Option<i64>,
+ #[serde(rename = "type")]
+ pub r#type: Option<AttachmentType>,
pub uuid: Option<String>,
}
+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+pub enum AttachmentType {
+ #[serde(rename = "attachment")]
+ Attachment,
+ #[serde(rename = "external")]
+ External,
+}
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct BlockedUser {
pub block_id: Option<i64>,
@@ -767,8 +785,62 @@ pub struct CreatePushMirrorOption {
pub remote_password: Option<String>,
pub remote_username: Option<String>,
pub sync_on_commit: Option<bool>,
+ pub use_ssh: Option<bool>,
}
+/// CreateQutaGroupOptions represents the options for creating a quota group
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct CreateQuotaGroupOptions {
+ /// Name of the quota group to create
+ pub name: Option<String>,
+ /// Rules to add to the newly created group.
+ ///
+ /// If a rule does not exist, it will be created.
+ pub rules: Option<Vec<CreateQuotaRuleOptions>>,
+}
+
+/// CreateQuotaRuleOptions represents the options for creating a quota rule
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct CreateQuotaRuleOptions {
+ /// The limit set by the rule
+ pub limit: Option<i64>,
+ /// Name of the rule to create
+ pub name: Option<String>,
+ /// The subjects affected by the rule
+ pub subjects: Option<Vec<CreateQuotaRuleOptionsSubjects>>,
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
+pub enum CreateQuotaRuleOptionsSubjects {
+ #[serde(rename = "none")]
+ None,
+ #[serde(rename = "size:all")]
+ SizeAll,
+ #[serde(rename = "size:repos:all")]
+ SizeReposAll,
+ #[serde(rename = "size:repos:public")]
+ SizeReposPublic,
+ #[serde(rename = "size:repos:private")]
+ SizeReposPrivate,
+ #[serde(rename = "size:git:all")]
+ SizeGitAll,
+ #[serde(rename = "size:git:lfs")]
+ SizeGitLfs,
+ #[serde(rename = "size:assets:all")]
+ SizeAssetsAll,
+ #[serde(rename = "size:assets:attachments:all")]
+ SizeAssetsAttachmentsAll,
+ #[serde(rename = "size:assets:attachments:issues")]
+ SizeAssetsAttachmentsIssues,
+ #[serde(rename = "size:assets:attachments:releases")]
+ SizeAssetsAttachmentsReleases,
+ #[serde(rename = "size:assets:artifacts")]
+ SizeAssetsArtifacts,
+ #[serde(rename = "size:assets:packages:all")]
+ SizeAssetsPackagesAll,
+ #[serde(rename = "size:assets:wiki")]
+ SizeAssetsWiki,
+}
/// CreateReleaseOption options when creating a release
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct CreateReleaseOption {
@@ -1004,6 +1076,9 @@ pub struct DispatchWorkflowOption {
/// EditAttachmentOptions options for editing attachments
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct EditAttachmentOptions {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// (Can only be set if existing attachment is of external type)
+ pub browser_download_url: Option<url::Url>,
pub name: Option<String>,
}
@@ -1146,6 +1221,15 @@ pub struct EditPullRequestOption {
pub unset_due_date: Option<bool>,
}
+/// EditQuotaRuleOptions represents the options for editing a quota rule
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct EditQuotaRuleOptions {
+ /// The limit set by the rule
+ pub limit: Option<i64>,
+ /// The subjects affected by the rule
+ pub subjects: Option<Vec<String>>,
+}
+
/// EditReactionOption contain the reaction type
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct EditReactionOption {
@@ -2192,6 +2276,7 @@ pub struct PullRequest {
pub pin_order: Option<i64>,
#[serde(deserialize_with = "crate::requested_reviewers_ignore_null")]
pub requested_reviewers: Option<Vec<User>>,
+ pub requested_reviewers_teams: Option<Vec<Team>>,
/// 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>,
@@ -2277,12 +2362,150 @@ pub struct PushMirror {
pub last_error: Option<String>,
#[serde(with = "time::serde::rfc3339::option")]
pub last_update: Option<time::OffsetDateTime>,
+ pub public_key: Option<String>,
pub remote_address: Option<String>,
pub remote_name: Option<String>,
pub repo_name: Option<String>,
pub sync_on_commit: Option<bool>,
}
+/// QuotaGroup represents a quota group
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaGroup {
+ /// Name of the group
+ pub name: Option<String>,
+ /// Rules associated with the group
+ pub rules: Option<Vec<QuotaRuleInfo>>,
+}
+
+/// QuotaInfo represents information about a user's quota
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaInfo {
+ pub groups: Option<Vec<QuotaGroup>>,
+ pub used: Option<QuotaUsed>,
+}
+
+/// QuotaRuleInfo contains information about a quota rule
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaRuleInfo {
+ /// The limit set by the rule
+ pub limit: Option<i64>,
+ /// Name of the rule (only shown to admins)
+ pub name: Option<String>,
+ /// Subjects the rule affects
+ pub subjects: Option<Vec<String>>,
+}
+
+/// QuotaUsed represents the quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsed {
+ pub size: Option<QuotaUsedSize>,
+}
+
+/// QuotaUsedArtifact represents an artifact counting towards a user's quota
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedArtifact {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// HTML URL to the action run containing the artifact
+ pub html_url: Option<url::Url>,
+ /// Name of the artifact
+ pub name: Option<String>,
+ /// Size of the artifact (compressed)
+ pub size: Option<i64>,
+}
+
+/// QuotaUsedAttachment represents an attachment counting towards a user's quota
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedAttachment {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// API URL for the attachment
+ pub api_url: Option<url::Url>,
+ /// Context for the attachment: URLs to the containing object
+ pub contained_in: Option<QuotaUsedAttachmentContainedIn>,
+ /// Filename of the attachment
+ pub name: Option<String>,
+ /// Size of the attachment (in bytes)
+ pub size: Option<i64>,
+}
+
+/// Context for the attachment: URLs to the containing object
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedAttachmentContainedIn {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// API URL for the object that contains this attachment
+ pub api_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// HTML URL for the object that contains this attachment
+ pub html_url: Option<url::Url>,
+}
+
+/// QuotaUsedPackage represents a package counting towards a user's quota
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedPackage {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ /// HTML URL to the package version
+ pub html_url: Option<url::Url>,
+ /// Name of the package
+ pub name: Option<String>,
+ /// Size of the package version
+ pub size: Option<i64>,
+ /// Type of the package
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ /// Version of the package
+ pub version: Option<String>,
+}
+
+/// QuotaUsedSize represents the size-based quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSize {
+ pub assets: Option<QuotaUsedSizeAssets>,
+ pub git: Option<QuotaUsedSizeGit>,
+ pub repos: Option<QuotaUsedSizeRepos>,
+}
+
+/// QuotaUsedSizeAssets represents the size-based asset usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSizeAssets {
+ /// Storage size used for the user's artifacts
+ pub artifacts: Option<i64>,
+ pub attachments: Option<QuotaUsedSizeAssetsAttachments>,
+ pub packages: Option<QuotaUsedSizeAssetsPackages>,
+}
+
+/// QuotaUsedSizeAssetsAttachments represents the size-based attachment quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSizeAssetsAttachments {
+ /// Storage size used for the user's issue & comment attachments
+ pub issues: Option<i64>,
+ /// Storage size used for the user's release attachments
+ pub releases: Option<i64>,
+}
+
+/// QuotaUsedSizeAssetsPackages represents the size-based package quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSizeAssetsPackages {
+ /// Storage suze used for the user's packages
+ pub all: Option<i64>,
+}
+
+/// QuotaUsedSizeGit represents the size-based git (lfs) quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSizeGit {
+ /// Storage size of the user's Git LFS objects
+ #[serde(rename = "LFS")]
+ pub lfs: Option<i64>,
+}
+
+/// QuotaUsedSizeRepos represents the size-based repository quota usage of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct QuotaUsedSizeRepos {
+ /// Storage size of the user's private repositories
+ pub private: Option<i64>,
+ /// Storage size of the user's public repositories
+ pub public: Option<i64>,
+}
+
/// Reaction contain one reaction
#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Reaction {
@@ -2491,6 +2714,13 @@ pub struct ServerVersion {
pub version: Option<String>,
}
+/// SetUserQuotaGroupsOptions represents the quota groups of a user
+#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
+pub struct SetUserQuotaGroupsOptions {
+ /// Quota groups the user shall have
+ pub groups: Vec<String>,
+}
+
/// StateType issue state type
#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
@@ -3091,6 +3321,46 @@ impl TryFrom<&reqwest::header::HeaderMap> for InvalidTopicsErrorHeaders {
}
}
+pub struct QuotaExceededHeaders {
+ pub message: Option<String>,
+ pub user_id: Option<i64>,
+ pub username: Option<String>,
+}
+
+impl TryFrom<&reqwest::header::HeaderMap> for QuotaExceededHeaders {
+ 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 user_id = map
+ .get("user_id")
+ .map(|s| -> Result<_, _> {
+ let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?;
+ s.parse::<i64>()
+ .map_err(|_| StructureError::HeaderParseFailed)
+ })
+ .transpose()?;
+ let username = map
+ .get("username")
+ .map(|s| -> Result<_, _> {
+ let s = s.to_str().map_err(|_| StructureError::HeaderNotAscii)?;
+ Ok(s.to_string())
+ })
+ .transpose()?;
+ Ok(Self {
+ message,
+ user_id,
+ username,
+ })
+ }
+}
+
pub struct RepoArchivedErrorHeaders {
pub message: Option<String>,
pub url: Option<url::Url>,
@@ -3682,6 +3952,69 @@ impl std::fmt::Display for OrgListPublicMembersQuery {
}
#[derive(Debug, Clone, PartialEq, Default)]
+pub struct OrgListQuotaArtifactsQuery {
+ /// 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 OrgListQuotaArtifactsQuery {
+ 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 OrgListQuotaAttachmentsQuery {
+ /// 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 OrgListQuotaAttachmentsQuery {
+ 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 OrgListQuotaPackagesQuery {
+ /// 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 OrgListQuotaPackagesQuery {
+ 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>,
@@ -6072,11 +6405,76 @@ impl std::fmt::Display for OrgListCurrentUserOrgsQuery {
}
#[derive(Debug, Clone, PartialEq, Default)]
+pub struct UserListQuotaArtifactsQuery {
+ /// 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 UserListQuotaArtifactsQuery {
+ 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 UserListQuotaAttachmentsQuery {
+ /// 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 UserListQuotaAttachmentsQuery {
+ 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 UserListQuotaPackagesQuery {
+ /// 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 UserListQuotaPackagesQuery {
+ 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>,
+ /// order the repositories by name (default), id, or size
+ pub order_by: Option<String>,
}
impl std::fmt::Display for UserCurrentListReposQuery {
@@ -6087,6 +6485,9 @@ impl std::fmt::Display for UserCurrentListReposQuery {
if let Some(limit) = &self.limit {
write!(f, "limit={limit}&")?;
}
+ if let Some(order_by) = &self.order_by {
+ write!(f, "order_by={order_by}&")?;
+ }
Ok(())
}
diff --git a/swagger.v1.json b/swagger.v1.json
index 4fe69c0..13b13ad 100644
--- a/swagger.v1.json
+++ b/swagger.v1.json
@@ -7,13 +7,39 @@
"description": "This documentation describes the Forgejo API.",
"title": "Forgejo API",
"license": {
- "name": "MIT",
+ "name": "This file is distributed under the MIT license for the purpose of interoperability",
"url": "http://opensource.org/licenses/MIT"
},
- "version": "8.0.0-dev-1514-f9ad844fd6+gitea-1.22.0"
+ "version": "9.0.0-dev-1111-0496e72d15+gitea-1.22.0"
},
"basePath": "/api/v1",
"paths": {
+ "/activitypub/actor": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["activitypub"],
+ "summary": "Returns the instance's Actor",
+ "operationId": "activitypubInstanceActor",
+ "responses": {
+ "200": {
+ "$ref": "#/responses/ActivityPub"
+ }
+ }
+ }
+ },
+ "/activitypub/actor/inbox": {
+ "post": {
+ "produces": ["application/json"],
+ "tags": ["activitypub"],
+ "summary": "Send to the inbox",
+ "operationId": "activitypubInstanceActorInbox",
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ }
+ }
+ }
+ },
"/activitypub/repository-id/{repository-id}": {
"get": {
"produces": ["application/json"],
@@ -392,6 +418,457 @@
}
}
},
+ "/admin/quota/groups": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "List the available quota groups",
+ "operationId": "adminListQuotaGroups",
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaGroupList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ },
+ "post": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Create a new quota group",
+ "operationId": "adminCreateQuotaGroup",
+ "parameters": [
+ {
+ "description": "Definition of the quota group",
+ "name": "group",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateQuotaGroupOptions"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "$ref": "#/responses/QuotaGroup"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "409": {
+ "$ref": "#/responses/error"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
+ "/admin/quota/groups/{quotagroup}": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Get information about the quota group",
+ "operationId": "adminGetQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to query",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaGroup"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ },
+ "delete": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Delete a quota group",
+ "operationId": "adminDeleteQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to delete",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/admin/quota/groups/{quotagroup}/rules/{quotarule}": {
+ "put": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Adds a rule to a quota group",
+ "operationId": "adminAddRuleToQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to add a rule to",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "the name of the quota rule to add to the group",
+ "name": "quotarule",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "409": {
+ "$ref": "#/responses/error"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ },
+ "delete": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Removes a rule from a quota group",
+ "operationId": "adminRemoveRuleFromQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to remove a rule from",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "the name of the quota rule to remove from the group",
+ "name": "quotarule",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/admin/quota/groups/{quotagroup}/users": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "List users in a quota group",
+ "operationId": "adminListUsersInQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to list members of",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/UserList"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/admin/quota/groups/{quotagroup}/users/{username}": {
+ "put": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Add a user to a quota group",
+ "operationId": "adminAddUserToQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to add the user to",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "username of the user to add to the quota group",
+ "name": "username",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "409": {
+ "$ref": "#/responses/error"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ },
+ "delete": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Remove a user from a quota group",
+ "operationId": "adminRemoveUserFromQuotaGroup",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota group to remove a user from",
+ "name": "quotagroup",
+ "in": "path",
+ "required": true
+ },
+ {
+ "type": "string",
+ "description": "username of the user to remove from the quota group",
+ "name": "username",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/admin/quota/rules": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "List the available quota rules",
+ "operationId": "adminListQuotaRules",
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaRuleInfoList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ },
+ "post": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Create a new quota rule",
+ "operationId": "adminCreateQuotaRule",
+ "parameters": [
+ {
+ "description": "Definition of the quota rule",
+ "name": "rule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/CreateQuotaRuleOptions"
+ }
+ }
+ ],
+ "responses": {
+ "201": {
+ "$ref": "#/responses/QuotaRuleInfo"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "409": {
+ "$ref": "#/responses/error"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
+ "/admin/quota/rules/{quotarule}": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Get information about a quota rule",
+ "operationId": "adminGetQuotaRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota rule to query",
+ "name": "quotarule",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaRuleInfo"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ },
+ "delete": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Deletes a quota rule",
+ "operationId": "adminDeleteQuotaRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "quota rule to delete",
+ "name": "quotarule",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ },
+ "patch": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Change an existing quota rule",
+ "operationId": "adminEditQuotaRule",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "Quota rule to change",
+ "name": "quotarule",
+ "in": "path",
+ "required": true
+ },
+ {
+ "name": "rule",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/EditQuotaRuleOptions"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaRuleInfo"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
"/admin/runners/registration-token": {
"get": {
"produces": ["application/json"],
@@ -766,6 +1243,83 @@
}
}
},
+ "/admin/users/{username}/quota": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Get the user's quota info",
+ "operationId": "adminGetUserQuota",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "username of user to query",
+ "name": "username",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaInfo"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
+ "/admin/users/{username}/quota/groups": {
+ "post": {
+ "produces": ["application/json"],
+ "tags": ["admin"],
+ "summary": "Set the user's quota groups to a given list.",
+ "operationId": "adminSetUserQuotaGroups",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "username of the user to modify the quota groups from",
+ "name": "username",
+ "in": "path",
+ "required": true
+ },
+ {
+ "description": "list of groups that the user should be a member of",
+ "name": "groups",
+ "in": "body",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/SetUserQuotaGroupsOptions"
+ }
+ }
+ ],
+ "responses": {
+ "204": {
+ "$ref": "#/responses/empty"
+ },
+ "400": {
+ "$ref": "#/responses/error"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
"/admin/users/{username}/rename": {
"post": {
"produces": ["application/json"],
@@ -1075,7 +1629,7 @@
"type": "string"
},
"collectionFormat": "multi",
- "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned.",
+ "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread \u0026 pinned.",
"name": "status-types",
"in": "query"
},
@@ -1578,12 +2132,14 @@
},
{
"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"
@@ -2527,6 +3083,191 @@
}
}
},
+ "/orgs/{org}/quota": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["organization"],
+ "summary": "Get quota information for an organization",
+ "operationId": "orgGetQuota",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "name of the organization",
+ "name": "org",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaInfo"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/orgs/{org}/quota/artifacts": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["organization"],
+ "summary": "List the artifacts affecting the organization's quota",
+ "operationId": "orgListQuotaArtifacts",
+ "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/QuotaUsedArtifactList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/orgs/{org}/quota/attachments": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["organization"],
+ "summary": "List the attachments affecting the organization's quota",
+ "operationId": "orgListQuotaAttachments",
+ "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/QuotaUsedAttachmentList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
+ "/orgs/{org}/quota/check": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["organization"],
+ "summary": "Check if the organization is over quota for a given subject",
+ "operationId": "orgCheckQuota",
+ "parameters": [
+ {
+ "type": "string",
+ "description": "name of the organization",
+ "name": "org",
+ "in": "path",
+ "required": true
+ }
+ ],
+ "responses": {
+ "200": {
+ "$ref": "#/responses/boolean"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
+ "/orgs/{org}/quota/packages": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["organization"],
+ "summary": "List the packages affecting the organization's quota",
+ "operationId": "orgListQuotaPackages",
+ "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/QuotaUsedPackageList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "404": {
+ "$ref": "#/responses/notFound"
+ }
+ }
+ }
+ },
"/orgs/{org}/repos": {
"get": {
"produces": ["application/json"],
@@ -3133,6 +3874,9 @@
"409": {
"description": "The repository with the same name already exists."
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -3374,6 +4118,35 @@
}
}
},
+ "/repos/{owner}/{repo}/actions/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}/actions/secrets": {
"get": {
"produces": ["application/json"],
@@ -3397,12 +4170,14 @@
},
{
"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"
@@ -3535,12 +4310,14 @@
},
{
"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"
@@ -3591,12 +4368,14 @@
},
{
"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"
@@ -4333,6 +5112,9 @@
"409": {
"description": "The branch with the same name already exists."
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -5013,6 +5795,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/error"
},
@@ -5113,6 +5898,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/error"
},
@@ -5168,6 +5956,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/error"
},
@@ -5226,6 +6017,9 @@
"404": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -5270,6 +6064,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -5637,6 +6434,9 @@
"409": {
"description": "The repository with the same name already exists."
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -6983,6 +7783,9 @@
"404": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
},
@@ -7140,6 +7943,9 @@
"404": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -7554,6 +8360,9 @@
"404": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
},
@@ -7711,6 +8520,9 @@
"404": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -9873,7 +10685,7 @@
},
"/repos/{owner}/{repo}/media/{filepath}": {
"get": {
- "produces": ["*/*"],
+ "produces": ["application/octet-stream"],
"tags": ["repository"],
"summary": "Get a file or it's LFS object from a repository",
"operationId": "repoGetRawFileOrLFS",
@@ -10163,6 +10975,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -10233,7 +11048,7 @@
"type": "string"
},
"collectionFormat": "multi",
- "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread & pinned",
+ "description": "Show notifications with the provided status types. Options are: unread, read and/or pinned. Defaults to unread \u0026 pinned",
"name": "status-types",
"in": "query"
},
@@ -10464,6 +11279,9 @@
"409": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
},
@@ -10924,6 +11742,9 @@
"409": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -11721,6 +12542,9 @@
"409": {
"$ref": "#/responses/error"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -11819,6 +12643,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -11857,6 +12684,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -11948,7 +12778,7 @@
},
"/repos/{owner}/{repo}/raw/{filepath}": {
"get": {
- "produces": ["*/*"],
+ "produces": ["application/octet-stream"],
"tags": ["repository"],
"summary": "Get a file from a repository",
"operationId": "repoGetRawFile",
@@ -12405,9 +13235,15 @@
},
{
"type": "file",
- "description": "attachment to upload",
+ "description": "attachment to upload (this parameter is incompatible with `external_url`)",
"name": "attachment",
"in": "formData"
+ },
+ {
+ "type": "string",
+ "description": "url to external asset (this parameter is incompatible with `attachment`)",
+ "name": "external_url",
+ "in": "formData"
}
],
"responses": {
@@ -12419,6 +13255,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -12567,6 +13406,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -12603,35 +13445,6 @@
}
}
},
- "/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"],
@@ -13257,6 +14070,9 @@
"409": {
"$ref": "#/responses/conflict"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
},
@@ -13841,6 +14657,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -13878,6 +14697,9 @@
},
"404": {
"$ref": "#/responses/notFound"
+ },
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
}
}
}
@@ -13959,6 +14781,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -14093,6 +14918,9 @@
"404": {
"$ref": "#/responses/notFound"
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"423": {
"$ref": "#/responses/repoArchivedError"
}
@@ -14234,6 +15062,9 @@
"409": {
"description": "The repository with the same name already exists."
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -14902,12 +15733,14 @@
"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"
@@ -15883,6 +16716,137 @@
}
}
},
+ "/user/quota": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["user"],
+ "summary": "Get quota information for the authenticated user",
+ "operationId": "userGetQuota",
+ "responses": {
+ "200": {
+ "$ref": "#/responses/QuotaInfo"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ }
+ },
+ "/user/quota/artifacts": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["user"],
+ "summary": "List the artifacts affecting the authenticated user's quota",
+ "operationId": "userListQuotaArtifacts",
+ "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/QuotaUsedArtifactList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ }
+ },
+ "/user/quota/attachments": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["user"],
+ "summary": "List the attachments affecting the authenticated user's quota",
+ "operationId": "userListQuotaAttachments",
+ "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/QuotaUsedAttachmentList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ }
+ },
+ "/user/quota/check": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["user"],
+ "summary": "Check if the authenticated user is over quota for a given subject",
+ "operationId": "userCheckQuota",
+ "responses": {
+ "200": {
+ "$ref": "#/responses/boolean"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
+ }
+ }
+ }
+ },
+ "/user/quota/packages": {
+ "get": {
+ "produces": ["application/json"],
+ "tags": ["user"],
+ "summary": "List the packages affecting the authenticated user's quota",
+ "operationId": "userListQuotaPackages",
+ "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/QuotaUsedPackageList"
+ },
+ "403": {
+ "$ref": "#/responses/forbidden"
+ }
+ }
+ }
+ },
"/user/repos": {
"get": {
"produces": ["application/json"],
@@ -15903,11 +16867,20 @@
"description": "page size of results",
"name": "limit",
"in": "query"
+ },
+ {
+ "type": "string",
+ "description": "order the repositories by name (default), id, or size",
+ "name": "order_by",
+ "in": "query"
}
],
"responses": {
"200": {
"$ref": "#/responses/RepositoryList"
+ },
+ "422": {
+ "$ref": "#/responses/validationError"
}
}
},
@@ -15936,6 +16909,9 @@
"409": {
"description": "The repository with the same name already exists."
},
+ "413": {
+ "$ref": "#/responses/quotaExceeded"
+ },
"422": {
"$ref": "#/responses/validationError"
}
@@ -17188,6 +18164,7 @@
"properties": {
"permission": {
"type": "string",
+ "enum": ["read", "write", "admin"],
"x-go-name": "Permission"
}
},
@@ -17306,6 +18283,11 @@
"format": "int64",
"x-go-name": "Size"
},
+ "type": {
+ "type": "string",
+ "enum": ["attachment", "external"],
+ "x-go-name": "Type"
+ },
"uuid": {
"type": "string",
"x-go-name": "UUID"
@@ -18733,6 +19715,72 @@
"sync_on_commit": {
"type": "boolean",
"x-go-name": "SyncOnCommit"
+ },
+ "use_ssh": {
+ "type": "boolean",
+ "x-go-name": "UseSSH"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "CreateQuotaGroupOptions": {
+ "description": "CreateQutaGroupOptions represents the options for creating a quota group",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Name of the quota group to create",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "rules": {
+ "description": "Rules to add to the newly created group.\nIf a rule does not exist, it will be created.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/CreateQuotaRuleOptions"
+ },
+ "x-go-name": "Rules"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "CreateQuotaRuleOptions": {
+ "description": "CreateQuotaRuleOptions represents the options for creating a quota rule",
+ "type": "object",
+ "properties": {
+ "limit": {
+ "description": "The limit set by the rule",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Limit"
+ },
+ "name": {
+ "description": "Name of the rule to create",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "subjects": {
+ "description": "The subjects affected by the rule",
+ "type": "array",
+ "items": {
+ "type": "string",
+ "enum": [
+ "none",
+ "size:all",
+ "size:repos:all",
+ "size:repos:public",
+ "size:repos:private",
+ "size:git:all",
+ "size:git:lfs",
+ "size:assets:all",
+ "size:assets:attachments:all",
+ "size:assets:attachments:issues",
+ "size:assets:attachments:releases",
+ "size:assets:artifacts",
+ "size:assets:packages:all",
+ "size:assets:wiki"
+ ]
+ },
+ "x-go-name": "Subjects"
}
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
@@ -19250,6 +20298,12 @@
"description": "EditAttachmentOptions options for editing attachments",
"type": "object",
"properties": {
+ "browser_download_url": {
+ "description": "(Can only be set if existing attachment is of external type)",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "DownloadURL"
+ },
"name": {
"type": "string",
"x-go-name": "Name"
@@ -19657,6 +20711,27 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
+ "EditQuotaRuleOptions": {
+ "description": "EditQuotaRuleOptions represents the options for editing a quota rule",
+ "type": "object",
+ "properties": {
+ "limit": {
+ "description": "The limit set by the rule",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Limit"
+ },
+ "subjects": {
+ "description": "The subjects affected by the rule",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "x-go-name": "Subjects"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
"EditReactionOption": {
"description": "EditReactionOption contain the reaction type",
"type": "object",
@@ -22207,6 +23282,13 @@
},
"x-go-name": "RequestedReviewers"
},
+ "requested_reviewers_teams": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/Team"
+ },
+ "x-go-name": "RequestedReviewersTeams"
+ },
"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",
@@ -22446,6 +23528,10 @@
"format": "date-time",
"x-go-name": "LastUpdateUnix"
},
+ "public_key": {
+ "type": "string",
+ "x-go-name": "PublicKey"
+ },
"remote_address": {
"type": "string",
"x-go-name": "RemoteAddress"
@@ -22465,6 +23551,306 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
+ "QuotaGroup": {
+ "description": "QuotaGroup represents a quota group",
+ "type": "object",
+ "properties": {
+ "name": {
+ "description": "Name of the group",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "rules": {
+ "description": "Rules associated with the group",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaRuleInfo"
+ },
+ "x-go-name": "Rules"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaGroupList": {
+ "description": "QuotaGroupList represents a list of quota groups",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaGroup"
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaInfo": {
+ "description": "QuotaInfo represents information about a user's quota",
+ "type": "object",
+ "properties": {
+ "groups": {
+ "$ref": "#/definitions/QuotaGroupList"
+ },
+ "used": {
+ "$ref": "#/definitions/QuotaUsed"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaRuleInfo": {
+ "description": "QuotaRuleInfo contains information about a quota rule",
+ "type": "object",
+ "properties": {
+ "limit": {
+ "description": "The limit set by the rule",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Limit"
+ },
+ "name": {
+ "description": "Name of the rule (only shown to admins)",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "subjects": {
+ "description": "Subjects the rule affects",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "x-go-name": "Subjects"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsed": {
+ "description": "QuotaUsed represents the quota usage of a user",
+ "type": "object",
+ "properties": {
+ "size": {
+ "$ref": "#/definitions/QuotaUsedSize"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedArtifact": {
+ "description": "QuotaUsedArtifact represents an artifact counting towards a user's quota",
+ "type": "object",
+ "properties": {
+ "html_url": {
+ "description": "HTML URL to the action run containing the artifact",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "HTMLURL"
+ },
+ "name": {
+ "description": "Name of the artifact",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "size": {
+ "description": "Size of the artifact (compressed)",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Size"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedArtifactList": {
+ "description": "QuotaUsedArtifactList represents a list of artifacts counting towards a user's quota",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaUsedArtifact"
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedAttachment": {
+ "description": "QuotaUsedAttachment represents an attachment counting towards a user's quota",
+ "type": "object",
+ "properties": {
+ "api_url": {
+ "description": "API URL for the attachment",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "APIURL"
+ },
+ "contained_in": {
+ "description": "Context for the attachment: URLs to the containing object",
+ "type": "object",
+ "properties": {
+ "api_url": {
+ "description": "API URL for the object that contains this attachment",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "APIURL"
+ },
+ "html_url": {
+ "description": "HTML URL for the object that contains this attachment",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "HTMLURL"
+ }
+ },
+ "x-go-name": "ContainedIn"
+ },
+ "name": {
+ "description": "Filename of the attachment",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "size": {
+ "description": "Size of the attachment (in bytes)",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Size"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedAttachmentList": {
+ "description": "QuotaUsedAttachmentList represents a list of attachment counting towards a user's quota",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaUsedAttachment"
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedPackage": {
+ "description": "QuotaUsedPackage represents a package counting towards a user's quota",
+ "type": "object",
+ "properties": {
+ "html_url": {
+ "description": "HTML URL to the package version",
+ "type": "string",
+ "format": "url",
+ "x-go-name": "HTMLURL"
+ },
+ "name": {
+ "description": "Name of the package",
+ "type": "string",
+ "x-go-name": "Name"
+ },
+ "size": {
+ "description": "Size of the package version",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Size"
+ },
+ "type": {
+ "description": "Type of the package",
+ "type": "string",
+ "x-go-name": "Type"
+ },
+ "version": {
+ "description": "Version of the package",
+ "type": "string",
+ "x-go-name": "Version"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedPackageList": {
+ "description": "QuotaUsedPackageList represents a list of packages counting towards a user's quota",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaUsedPackage"
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSize": {
+ "description": "QuotaUsedSize represents the size-based quota usage of a user",
+ "type": "object",
+ "properties": {
+ "assets": {
+ "$ref": "#/definitions/QuotaUsedSizeAssets"
+ },
+ "git": {
+ "$ref": "#/definitions/QuotaUsedSizeGit"
+ },
+ "repos": {
+ "$ref": "#/definitions/QuotaUsedSizeRepos"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSizeAssets": {
+ "description": "QuotaUsedSizeAssets represents the size-based asset usage of a user",
+ "type": "object",
+ "properties": {
+ "artifacts": {
+ "description": "Storage size used for the user's artifacts",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Artifacts"
+ },
+ "attachments": {
+ "$ref": "#/definitions/QuotaUsedSizeAssetsAttachments"
+ },
+ "packages": {
+ "$ref": "#/definitions/QuotaUsedSizeAssetsPackages"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSizeAssetsAttachments": {
+ "description": "QuotaUsedSizeAssetsAttachments represents the size-based attachment quota usage of a user",
+ "type": "object",
+ "properties": {
+ "issues": {
+ "description": "Storage size used for the user's issue \u0026 comment attachments",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Issues"
+ },
+ "releases": {
+ "description": "Storage size used for the user's release attachments",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Releases"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSizeAssetsPackages": {
+ "description": "QuotaUsedSizeAssetsPackages represents the size-based package quota usage of a user",
+ "type": "object",
+ "properties": {
+ "all": {
+ "description": "Storage suze used for the user's packages",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "All"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSizeGit": {
+ "description": "QuotaUsedSizeGit represents the size-based git (lfs) quota usage of a user",
+ "type": "object",
+ "properties": {
+ "LFS": {
+ "description": "Storage size of the user's Git LFS objects",
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
+ "QuotaUsedSizeRepos": {
+ "description": "QuotaUsedSizeRepos represents the size-based repository quota usage of a user",
+ "type": "object",
+ "properties": {
+ "private": {
+ "description": "Storage size of the user's private repositories",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Private"
+ },
+ "public": {
+ "description": "Storage size of the user's public repositories",
+ "type": "integer",
+ "format": "int64",
+ "x-go-name": "Public"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
"Reaction": {
"description": "Reaction contain one reaction",
"type": "object",
@@ -23043,6 +24429,22 @@
},
"x-go-package": "code.gitea.io/gitea/modules/structs"
},
+ "SetUserQuotaGroupsOptions": {
+ "description": "SetUserQuotaGroupsOptions represents the quota groups of a user",
+ "type": "object",
+ "required": ["groups"],
+ "properties": {
+ "groups": {
+ "description": "Quota groups the user shall have",
+ "type": "array",
+ "items": {
+ "type": "string"
+ },
+ "x-go-name": "Groups"
+ }
+ },
+ "x-go-package": "code.gitea.io/gitea/modules/structs"
+ },
"StateType": {
"description": "StateType issue state type",
"type": "string",
@@ -24648,6 +26050,57 @@
}
}
},
+ "QuotaGroup": {
+ "description": "QuotaGroup",
+ "schema": {
+ "$ref": "#/definitions/QuotaGroup"
+ }
+ },
+ "QuotaGroupList": {
+ "description": "QuotaGroupList",
+ "schema": {
+ "$ref": "#/definitions/QuotaGroupList"
+ }
+ },
+ "QuotaInfo": {
+ "description": "QuotaInfo",
+ "schema": {
+ "$ref": "#/definitions/QuotaInfo"
+ }
+ },
+ "QuotaRuleInfo": {
+ "description": "QuotaRuleInfo",
+ "schema": {
+ "$ref": "#/definitions/QuotaRuleInfo"
+ }
+ },
+ "QuotaRuleInfoList": {
+ "description": "QuotaRuleInfoList",
+ "schema": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/QuotaRuleInfo"
+ }
+ }
+ },
+ "QuotaUsedArtifactList": {
+ "description": "QuotaUsedArtifactList",
+ "schema": {
+ "$ref": "#/definitions/QuotaUsedArtifactList"
+ }
+ },
+ "QuotaUsedAttachmentList": {
+ "description": "QuotaUsedAttachmentList",
+ "schema": {
+ "$ref": "#/definitions/QuotaUsedAttachmentList"
+ }
+ },
+ "QuotaUsedPackageList": {
+ "description": "QuotaUsedPackageList",
+ "schema": {
+ "$ref": "#/definitions/QuotaUsedPackageList"
+ }
+ },
"Reaction": {
"description": "Reaction",
"schema": {
@@ -24947,6 +26400,9 @@
}
}
},
+ "boolean": {
+ "description": "Boolean"
+ },
"conflict": {
"description": "APIConflict is a conflict empty response"
},
@@ -24997,7 +26453,22 @@
"parameterBodies": {
"description": "parameterBodies",
"schema": {
- "$ref": "#/definitions/DispatchWorkflowOption"
+ "$ref": "#/definitions/SetUserQuotaGroupsOptions"
+ }
+ },
+ "quotaExceeded": {
+ "description": "QuotaExceeded",
+ "headers": {
+ "message": {
+ "type": "string"
+ },
+ "user_id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "username": {
+ "type": "string"
+ }
}
},
"redirect": {
diff --git a/tests/admin.rs b/tests/admin.rs
index 6b82fab..674ca16 100644
--- a/tests/admin.rs
+++ b/tests/admin.rs
@@ -188,3 +188,91 @@ async fn hook() {
.await
.expect("failed to delete hook");
}
+
+#[tokio::test]
+async fn quota_group() {
+ let api = common::login();
+
+ let user_opts = CreateUserOption {
+ created_at: None,
+ email: "1997@example.com".into(),
+ full_name: None,
+ login_name: None,
+ must_change_password: None,
+ password: Some("dialtone".into()),
+ restricted: None,
+ send_notify: None,
+ source_id: None,
+ username: "salesman".into(),
+ visibility: None,
+ };
+ api.admin_create_user(user_opts)
+ .await
+ .expect("failed to create user");
+
+ let group = CreateQuotaGroupOptions {
+ name: Some("no doing anything".into()),
+ rules: Some(vec![CreateQuotaRuleOptions {
+ limit: Some(0),
+ name: Some("blah".into()),
+ subjects: Some(vec![CreateQuotaRuleOptionsSubjects::SizeAll]),
+ }]),
+ };
+ let quota_group = api
+ .admin_create_quota_group(group)
+ .await
+ .expect("failed to create quota group");
+
+ api.admin_add_user_to_quota_group("no doing anything", "salesman")
+ .await
+ .expect("failed to add user to quota group");
+
+ assert!(quota_group
+ .name
+ .as_ref()
+ .is_some_and(|name| name == "no doing anything"));
+ assert!(quota_group
+ .rules
+ .as_ref()
+ .is_some_and(|rules| rules.len() == 1));
+
+ let quota_groups = api
+ .admin_list_quota_groups()
+ .await
+ .expect("failed to list quota groups");
+ assert_eq!(quota_groups.len(), 1);
+ assert_eq!(&quota_groups[0], &quota_group);
+
+ let quota_info = api
+ .admin_get_user_quota("salesman")
+ .await
+ .expect("failed to get user quota");
+ let usage = quota_info
+ .used
+ .expect("quota info missing usage info")
+ .size
+ .expect("quota info missing size info");
+ assert!(usage
+ .git
+ .is_some_and(|git| git.lfs.is_some_and(|lfs| lfs == 0)));
+ assert!(usage
+ .repos
+ .as_ref()
+ .is_some_and(|repos| repos.public.is_some_and(|lfs| lfs == 0)));
+ assert!(usage
+ .repos
+ .is_some_and(|repos| repos.private.is_some_and(|lfs| lfs == 0)));
+ assert!(usage
+ .assets
+ .is_some_and(|assets| assets.artifacts.is_some_and(|lfs| lfs == 0)));
+
+ api.admin_remove_rule_from_quota_group("no doing anything", "blah")
+ .await
+ .expect("failed to delete rule from quota group");
+ api.admin_remove_user_from_quota_group("no doing anything", "salesman")
+ .await
+ .expect("failed to remove user from quota group");
+ api.admin_delete_quota_group("no doing anything")
+ .await
+ .expect("failed to delete quota group");
+}
diff --git a/tests/repo.rs b/tests/repo.rs
index 3a0377c..b8e048a 100644
--- a/tests/repo.rs
+++ b/tests/repo.rs
@@ -271,7 +271,8 @@ async fn release() {
"TestingAdmin",
"release-test",
release.id.unwrap() as u64,
- b"This is a file!".to_vec(),
+ Some(b"This is a file!".to_vec()),
+ None,
RepoCreateReleaseAttachmentQuery {
name: Some("test.txt".into()),
},
@@ -390,7 +391,7 @@ async fn team_pr_review_request() {
.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()));
+ assert_eq!(pr.requested_reviewers, None);
}
#[tokio::test]