diff --git a/registry/src/errors.rs b/registry/src/errors.rs index a755de24..7aa86112 100644 --- a/registry/src/errors.rs +++ b/registry/src/errors.rs @@ -93,4 +93,7 @@ pub enum ExtensionRegistryError { #[error("Not a GitHub repository: {0}")] InvalidGithubRepo(String), + + #[error("Failed to decompress Trunk archive")] + ArchiveError, } diff --git a/registry/src/routes/extensions.rs b/registry/src/routes/extensions.rs index aa39fb52..71ec4e0c 100644 --- a/registry/src/routes/extensions.rs +++ b/registry/src/routes/extensions.rs @@ -11,7 +11,8 @@ use crate::readme::GithubApiClient; use crate::repository::Registry; use crate::token::validate_token; use crate::uploader::upload_extension; -use crate::v1::repository::TrunkProjectView; +use crate::v1::extractor; +use crate::v1::repository::{ExtensionView, TrunkProjectView}; use crate::views::extension_publish::ExtensionUpload; use crate::views::user_info::UserInfo; use actix_multipart::Multipart; @@ -289,6 +290,12 @@ pub async fn publish( // The uploaded contents in .tar.gz let gzipped_archive = file.freeze(); + // Extract the .tar.gz and its relevant contentss + let (extension_views, pg_version) = + extractor::extract_extension_view(&gzipped_archive, &new_extension).map_err(|err| { + tracing::error!("Failed to decompress archive: {err}"); + ExtensionRegistryError::ArchiveError + })?; // TODO(ianstanton) Generate checksum let file_byte_stream = ByteStream::from(gzipped_archive.clone()); @@ -299,6 +306,7 @@ pub async fn publish( file_byte_stream, &new_extension, &new_extension.vers, + pg_version, ) .await?; @@ -315,21 +323,25 @@ pub async fn publish( .await .map_err(|err| error!("Failed to fetch README in /publish: {err}")); - let _ = insert_into_v1(new_extension, registry.as_ref(), gzipped_archive.as_ref()) - .await - .map_err(|err| error!("Failed to insert extension into v1 in /publish: {err}")); + // Insert into v1 tables + let _ = insert_into_v1( + new_extension, + extension_views, + pg_version, + registry.as_ref(), + ) + .await + .map_err(|err| error!("Failed to insert extension into v1 in /publish: {err}")); Ok(response) } async fn insert_into_v1( new_extension: ExtensionUpload, + extension_views: Vec, + pg_version: u8, registry: &Registry, - gzipped_archive: &[u8], ) -> anyhow::Result<()> { - let (extension_views, pg_version) = - crate::v1::extractor::extract_extension_view(gzipped_archive, &new_extension)?; - let trunk_project = TrunkProjectView { name: new_extension.name, description: new_extension.description.unwrap_or_default(), diff --git a/registry/src/uploader.rs b/registry/src/uploader.rs index 0d6b9206..4e7e26aa 100644 --- a/registry/src/uploader.rs +++ b/registry/src/uploader.rs @@ -11,16 +11,23 @@ use tracing::{debug, info}; const CACHE_CONTROL_IMMUTABLE: &str = "public,max-age=31536000,immutable"; /// Returns the internal path of an uploaded extension's version archive. -fn extension_path(name: &str, version: &str) -> String { - format!("extensions/{name}/{name}-{version}.tar.gz") +fn extension_path(name: &str, extension_version: &str, pg_version: u8) -> String { + format!("extensions/{name}/{name}-pg{pg_version}-{extension_version}.tar.gz") } /// Returns the URL of an uploaded extension's version archive. /// /// The function doesn't check for the existence of the file. -pub fn extension_location(bucket_name: &str, project_name: &str, version: &str) -> String { +pub fn extension_location( + bucket_name: &str, + project_name: &str, + extension_version: &str, +) -> String { + // Note(vini): the current download endpoint only supports Postgres 15 + let pg_version = 15; + let host = format!("{bucket_name}.s3.amazonaws.com"); - let path = extension_path(project_name, version); + let path = extension_path(project_name, extension_version, pg_version); format!("https://{host}/{path}") } @@ -51,9 +58,10 @@ pub async fn upload_extension( s3_client: &aws_sdk_s3::Client, file: ByteStream, extension: &ExtensionUpload, - vers: &semver::Version, + extension_version: &semver::Version, + pg_version: u8, ) -> Result { - let path = extension_path(&extension.name, &vers.to_string()); + let path = extension_path(&extension.name, &extension_version.to_string(), pg_version); info!("Uploading extension: {:?}", extension); upload(bucket_name, s3_client, &path, file, "application/gzip").await?; Ok("Successfully uploaded extension".to_owned()) diff --git a/registry/src/v1/extractor.rs b/registry/src/v1/extractor.rs index a16bb07c..562698bc 100644 --- a/registry/src/v1/extractor.rs +++ b/registry/src/v1/extractor.rs @@ -1,6 +1,5 @@ use anyhow::Context; use flate2::read::GzDecoder; -use futures::io::BufReader; use serde::Deserialize; use std::{ ffi::OsStr,