Skip to main content
Glama
contribute.rs5.2 kB
use axum::{ Json, extract::Path, }; use chrono::Utc; use dal::{ SchemaVariant, module::Module, }; use module_index_client::ModuleIndexClient; use sdf_extract::{ PosthogEventTracker, change_set::ChangeSetDalContext, request::RawAccessToken, }; use serde_json::json; use si_events::audit_log::AuditLogKind; use utoipa::{ self, }; use super::{ SchemaError, SchemaResult, }; #[utoipa::path( post, path = "/v1/w/{workspace_id}/change-sets/{change_set_id}/schemas/{schema_id}/contribute", params( ("workspace_id" = String, Path, description = "Workspace identifier"), ("change_set_id" = String, Path, description = "Change Set identifier"), ("schema_id" = String, Path, description = "Schema identifier"), ), tag = "schemas", summary = "Contribute the default variant of a schema to the module index", responses( (status = 200, description = "Schema default variant contributed successfully"), (status = 400, description = "Bad request - Cannot contribute on head change set or default variant not locked or schema installed from upstream"), (status = 401, description = "Unauthorized - Invalid or missing token"), (status = 404, description = "Schema not found"), (status = 500, description = "Internal server error", body = crate::service::v1::common::ApiError) ) )] pub async fn contribute( ChangeSetDalContext(ref ctx): ChangeSetDalContext, RawAccessToken(raw_access_token): RawAccessToken, tracker: PosthogEventTracker, Path(super::SchemaV1RequestPath { schema_id }): Path<super::SchemaV1RequestPath>, ) -> SchemaResult<Json<serde_json::Value>> { // Check if the change set is HEAD - we ONLY allow contributions on HEAD let head_change_set_id = ctx.get_workspace_default_change_set_id().await?; if ctx.change_set_id() != head_change_set_id { return Err(SchemaError::ContributionsMustBeMadeFromHead); } // Get the default variant for the schema let schema_variant_id = dal::Schema::default_variant_id(ctx, schema_id).await?; let variant = SchemaVariant::get_by_id(ctx, schema_variant_id).await?; // Check if the variant is NOT locked - we only allow contributions on locked variants if !variant.is_locked() { return Err(SchemaError::ContributeUnlockedVariant(schema_variant_id)); } // We have 3 scenarios in which we accept contributions: // 1. A user downloads a builtin and immediately contributes it back // - This is not a usual scenario and something we will not accept anyway // 2. A user creates a modification of a builtin and contributes it back // - This is a more realistic scenario but all of our builtins are managed via clover // - So this isn't something we will support and we will document that for it not being // - the right way to change a builtin // 3. A user generates a NEW asset and wants to contribute it back to us // // It is on US as System Initiative to be able to effectively understand what differences // there are in the contribution. Stopping someone from contribute stops them from using // our tool and we should encourage their usage! let module_index_url = ctx .module_index_url() .ok_or(SchemaError::ModuleIndexNotConfigured)?; let index_client = ModuleIndexClient::new(module_index_url.try_into()?, &raw_access_token)?; let version = Utc::now().format("%Y%m%d%H%M%S").to_string(); let formatted_name = format!("{} {}", variant.display_name(), version); let ( name, version, based_on_hash, schema_id_from_module, payload, created_by_name, created_by_email, schema_variant_version, ) = Module::prepare_contribution(ctx, formatted_name, &version, schema_variant_id, false) .await?; let response = index_client .upload_module( name.as_str(), version.as_str(), based_on_hash.clone(), schema_id_from_module.map(|id| id.to_string()), payload.clone(), Some(schema_variant_id.to_string()), Some(schema_variant_version.clone()), Some(false), ) .await?; ctx.write_audit_log( AuditLogKind::ContributeModule { version: version.clone(), schema_id: schema_id_from_module, schema_variant_id: schema_variant_id.into(), schema_variant_version: Some(schema_variant_version.clone()), }, name.clone(), ) .await?; tracker.track( ctx, "api_contribute_schema", json!({ "pkg_name": name, "pkg_version": version, "based_on_hash": based_on_hash, "pkg_created_by_name": created_by_name, "pkg_created_by_email": created_by_email, "schema_variant_id": schema_variant_id, "schema_id": schema_id, "pkg_hash": response.latest_hash, }), ); ctx.commit().await?; Ok(Json(json!({ "success": true, "hash": response.latest_hash, }))) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server