Skip to content

Commit

Permalink
semver
Browse files Browse the repository at this point in the history
  • Loading branch information
o-tsaruk committed Aug 11, 2023
1 parent 80b146c commit 5d1b0e0
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 18 deletions.
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/builder/src/commands/serve.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@ pub enum ServeError {
pub async fn serve(
builder_config: config::Builder,
storage_config: config::Storage,
supported_cargo_contract_versions: Vec<String>,
database: DatabaseConnection,
) -> Result<(), Error> {
let builder_config = Arc::new(builder_config);
let storage_config = Arc::new(storage_config);
let supported_cargo_contract_versions = Arc::new(supported_cargo_contract_versions);
let docker = Arc::new(Docker::connect_with_socket_defaults()?);
let database = Arc::new(database);

Expand All @@ -40,6 +42,7 @@ pub async fn serve(
tokio::spawn(worker::spawn(
builder_config.clone(),
storage_config.clone(),
supported_cargo_contract_versions.clone(),
docker.clone(),
database.clone(),
sender.clone(),
Expand Down
10 changes: 9 additions & 1 deletion crates/builder/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,15 @@ async fn main() -> Result<(), anyhow::Error> {
info!("database connection established");

match cli.command {
Command::Serve => commands::serve(builder_config, config.storage, database).await?,
Command::Serve => {
commands::serve(
builder_config,
config.storage,
config.supported_cargo_contract_versions,
database,
)
.await?
}
}

Ok(())
Expand Down
34 changes: 33 additions & 1 deletion crates/builder/src/process/worker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pub(crate) enum WorkerError {
pub(crate) async fn spawn(
builder_config: Arc<config::Builder>,
storage_config: Arc<config::Storage>,
supported_cargo_contract_versions: Arc<Vec<String>>,
docker: Arc<Docker>,
db: Arc<DatabaseConnection>,
log_sender: UnboundedSender<LogEntry>,
Expand All @@ -58,6 +59,7 @@ pub(crate) async fn spawn(
.transaction::<_, _, WorkerError>(|txn| {
let builder_config = builder_config.clone();
let storage_config = storage_config.clone();
let supported_cargo_contract_versions = supported_cargo_contract_versions.clone();
let docker = docker.clone();
let log_sender = log_sender.clone();

Expand Down Expand Up @@ -94,7 +96,7 @@ pub(crate) async fn spawn(
)
.unarchive()
.await?
.build(log_sender)
.build(log_sender, &supported_cargo_contract_versions)
.await?
.get_files(wasm_buf, metadata_buf)
.await
Expand Down Expand Up @@ -196,6 +198,10 @@ enum SessionError {
/// Container ran out of time to complete the build.
#[display(fmt = "container timed out")]
TimedOut,

/// Unsupported cargo-contract version.
#[display(fmt = "unsupported cargo-contract version")]
UnsupportedCargoContractVersion,
}

/// Archived build session instance.
Expand Down Expand Up @@ -319,9 +325,35 @@ impl<'a> UnarchivedInstance<'a> {
pub async fn build(
self,
log_sender: UnboundedSender<LogEntry>,
supported_cargo_contract_versions: &[String],
) -> Result<BuiltInstance<'a>, SessionError> {
debug!("spawning container for building purposes");

if !supported_cargo_contract_versions.contains(&self.build_session.cargo_contract_version) {
let result = log_sender
.send(LogEntry {
build_session_id: self.build_session.id,
text: String::from("Provided cargo-contract version is not supported.\n"),
})
.and_then(|_| {
log_sender.send(LogEntry {
build_session_id: self.build_session.id,
text: format!(
"Consider using version {}",
supported_cargo_contract_versions.first().expect(
"at least one cargo-contract version is expected to be supported"
)
),
})
});

if let Err(e) = result {
error!(%e, "unable to send log entry")
}

return Err(SessionError::UnsupportedCargoContractVersion);
}

let container = match Container::new(
self.builder_config,
self.docker,
Expand Down
11 changes: 11 additions & 0 deletions crates/common/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,21 @@ pub struct Config {
/// Storage configuration.
pub storage: Storage,

/// Supported cargo-contract tooling versions.
///
/// Docker Hub tags can be used for reference.
#[serde(default = "default_supported_cargo_contract_versions")]
pub supported_cargo_contract_versions: Vec<String>,

/// Enable payments support.
#[serde(default = "default_payments")]
pub payments: bool,
}

fn default_supported_cargo_contract_versions() -> Vec<String> {
vec![String::from("4.0.0-alpha"), String::from("3.1.0")]
}

fn default_payments() -> bool {
false
}
Expand Down Expand Up @@ -207,6 +217,7 @@ impl Config {
endpoint_url: String::new(),
source_code_bucket: String::new(),
},
supported_cargo_contract_versions: default_supported_cargo_contract_versions(),
payments: false,
}
}
Expand Down
3 changes: 1 addition & 2 deletions crates/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,9 @@ derive_more = "0.99.17"
futures-util = "0.3.28"
hex = { version = "0.4.3", features = ["serde"] }
ink_metadata = "4.2.0"
once_cell = "1.17.1"
paste = "1.0.12"
regex = "1.8.1"
schemars = "0.8.12"
semver = "1.0.18"
serde = { version = "1.0.162", features = ["derive"] }
serde_plain = "1.0.1"
serde_json = "1.0.96"
Expand Down
21 changes: 10 additions & 11 deletions crates/server/src/handlers/build_sessions/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,14 @@ use db::{
EntityTrait, QuerySelect, SelectExt, TransactionErrorExt, TransactionTrait,
};
use derive_more::{Display, Error, From};
use once_cell::sync::Lazy;
use regex::Regex;
use schemars::JsonSchema;
use semver::Version;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use validator::Validate;
use validator::{Validate, ValidationError};

use crate::{auth::AuthenticatedUserId, schema::example_error, validation::ValidatedJson};

/// Regular expression to match stable versions of `cargo-contract`.
///
/// Currently, this regex does not support any nightly or unstable versions of the previously mentioned tooling.
static VERSION_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(r#"^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$"#).expect("invalid regex string")
});

/// Errors that may occur during the build session creation process.
#[derive(ErrorResponse, Display, From, Error, OperationIo)]
#[aide(output)]
Expand All @@ -50,11 +42,18 @@ pub(super) struct BuildSessionCreateRequest {
source_code_id: i64,

/// `cargo-contract` tooling version.
#[validate(regex = "VERSION_REGEX")]
#[validate(length(max = 32), custom = "validate_cargo_contract_version")]
#[schemars(example = "crate::schema::example_cargo_contract_version")]
cargo_contract_version: String,
}

/// Validate the provided cargo-contract version to be a valid Semver string.
fn validate_cargo_contract_version(cargo_contract_version: &str) -> Result<(), ValidationError> {
Version::parse(cargo_contract_version)
.map(|_| ())
.map_err(|_| ValidationError::new("invalid cargo-contract version"))
}

/// JSON response body.
#[derive(Serialize, JsonSchema)]
pub(super) struct BuildSessionCreateResponse {
Expand Down
2 changes: 1 addition & 1 deletion crates/server/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub(crate) fn example_error<E: Display + IntoResponse>(err: E) -> Value {
generate_examples!(
database_identifier, i64, 1;
hex_hash, HexHash, HexHash([200; 32]);
cargo_contract_version, String, String::from("3.0.1");
cargo_contract_version, String, String::from("4.0.0-alpha");
build_session_status, build_session::Status, build_session::Status::Completed;
log_position, Option<i64>, Some(40);
log_entry, String, String::from("Compiling futures-util v0.3.28");
Expand Down

0 comments on commit 5d1b0e0

Please sign in to comment.