From 024646acf49a9667b1c52aa0807d9e2531955d12 Mon Sep 17 00:00:00 2001 From: Robert Garrett Date: Sun, 14 Sep 2025 11:57:46 -0500 Subject: [PATCH] WIP: Deb upload, todos, and errata --- README.md | 8 +++++ src/api/packages.rs | 72 ++++++++++++++++++++++++++++++++++++++++++ src/structs/package.rs | 9 +++--- src/structs/release.rs | 1 + 4 files changed, 85 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 7ed9a36..9b4d7d9 100644 --- a/README.md +++ b/README.md @@ -126,3 +126,11 @@ Similar to how unspecified project settings will fall back to those in the "`[al | token | Gitea auth token, exactly the same as `$RELEASE_KEY_GITEA` | Additional keys are quietly ignored. The config loading is done by querying a HashMap, so anything not touched doesn't get inspected. The only requirements are that the file is valid TOML, and that these keys are all strings.h + +# Errata + +- Gitea's package *uploading* API endpoints are not documented with Swagger. + * https://github.com/go-gitea/gitea/issues/30597 + * It seems this is intentional because of which side defines the protocol (the consumer, not Gitea). + * This is an open issue (as of 12-Sep-2025) that doesn't have much attention. + * HTTP-POST (`curl`) is sufficient for upload. Use that either directly or as reference to make custom code. diff --git a/src/api/packages.rs b/src/api/packages.rs index aaaf8da..5f12a03 100644 --- a/src/api/packages.rs +++ b/src/api/packages.rs @@ -1,3 +1,5 @@ +use std::{fs, path::Path}; + use crate::structs::package::{Package, PackageType}; /// Gets all packages of an owner @@ -42,3 +44,73 @@ pub fn get_latest_package_version() {} pub fn link_package() {} pub fn unlink_package() {} pub fn search_packages() {} + + +/// Upload a Debian package and link it to it's source repository +fn upload_debian( + client: &reqwest::Client, + gitea_url: &str, + repo: &str, + file: &Path, + owner: &str, + distribution: &str, + component: &str, +) -> crate::Result<()> { + let request_url = format!("{gitea_url}/api/packages/{owner}/debian/pool/{distribution}/{component}/upload"); + match file.try_exists() { + Ok(true) => (), + Ok(false) => return Err(crate::Error::NoSuchFile), + Err(e) => { + eprintln!("Uh oh! The file-exists check couldn't be done: {e}"); + panic!( + "TODO: Deal with scenario where the file's existence cannot be checked (e.g.: no permission)" + ); + } + }; + + let data = reqwest::multipart::Part::stream(fs::read(&file).unwrap()) + .file_name("deb-pkg") + .mime_str("text/plain")?; + + Ok(()) +} + +/// Uploads a package file to the Gitea registry. +/// +/// This route is not documented in Swagger. The reason seems to be that some +/// package managers have their own upload protocol (e.g. `docker push`). Gitea +/// implements it but does not define it, so it doesn't include the API docs. +pub fn upload_package( + client: &reqwest::Client, + gitea_url: &str, + file: String, // TODO: Use a path buffer of some flavor. +) { + let request_url = format!("{gitea_url}/{}", route_for_upload(PackageType::Debian)); +} + +fn route_for_upload(kind: PackageType) -> &'static str { + match kind { + PackageType::Alpine => "https://gitea.example.com/api/packages/{owner}/alpine/{branch}/{repository}", + PackageType::Arch => "api/packages/{owner}/arch/{repository}", + PackageType::Cargo => todo!(), + PackageType::Chef => todo!(), + PackageType::Composer => todo!(), + PackageType::Conan => todo!(), + PackageType::Conda => todo!(), + PackageType::Container => todo!(), + PackageType::Cran => todo!(), + PackageType::Debian => "https://gitea.example.com/api/packages/{owner}/debian/pool/{distribution}/{component}/upload", + PackageType::Generic => todo!(), + PackageType::Go => todo!(), + PackageType::Helm => todo!(), + PackageType::Maven => todo!(), + PackageType::Npm => todo!(), + PackageType::Nuget => todo!(), + PackageType::Pub => todo!(), + PackageType::PyPi => todo!(), + PackageType::Rpm => todo!(), + PackageType::RubyGems => todo!(), + PackageType::Swift => todo!(), + PackageType::Vagrant => todo!(), + } +} \ No newline at end of file diff --git a/src/structs/package.rs b/src/structs/package.rs index d7631e2..139e501 100644 --- a/src/structs/package.rs +++ b/src/structs/package.rs @@ -24,15 +24,14 @@ pub struct Package { impl Package { pub fn colorized(&self) -> String { let name = "Name:".green().bold(); - let version = "Ver:".green(); - let pkg_type = "Type:".white(); + let version = &self.version; + let pkg_type = "Type:".green(); format!( - "{name} {} -{version} {}, {pkg_type} {}", + "{name} {} {version} +{pkg_type} {}", self.name, self.version, - self.pkg_type.to_string(), ) } } diff --git a/src/structs/release.rs b/src/structs/release.rs index 9ed537e..5165bc4 100644 --- a/src/structs/release.rs +++ b/src/structs/release.rs @@ -50,6 +50,7 @@ impl Release { } } +// TODO: Rename to "User" to match Gitea's code #[derive(Debug, Deserialize, Serialize)] pub struct Author { id: usize,