diff --git a/.cspell.json b/.cspell.json index e3fffbbda..5bb226cdb 100644 --- a/.cspell.json +++ b/.cspell.json @@ -1,5 +1,5 @@ { - "version": "0.1", + "version": "0.2", "language": "en", "ignorePaths": [ "**/contract/target/**", @@ -19,7 +19,8 @@ "crates/rust_analyzer_wasm/webdriver.json", "sysbox/*", "config/data/*", - "*.svg" + "*.svg", + "docker/*" ], "words": [ "dcdd", @@ -74,6 +75,7 @@ "rlib", "cdylib", "achimcc", + "radhezeeve", "prefill", "deserialization", "filesets", diff --git a/.github/workflows/compiler_docker.yml b/.github/workflows/compiler_docker.yml index f911d33bb..aef8689ea 100644 --- a/.github/workflows/compiler_docker.yml +++ b/.github/workflows/compiler_docker.yml @@ -12,8 +12,15 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Install jq + run: sudo apt -y install jq + + - name: Get last Ink version + id: version_info + run: echo "latest_ink_version=$(jq -r '.[0]' ./config/versions.json)" >> $GITHUB_OUTPUT + - name: Build docker - run: docker build -f Dockerfile.compiler --tag ink-compiler . + run: docker build -f ./docker/Dockerfile.compiler-${{ steps.version_info.outputs.latest_ink_version }} --tag ink-compiler:${{ steps.version_info.outputs.latest_ink_version }} ./docker - name: Login to DockerHub if: github.ref == 'refs/heads/main' && github.repository == 'paritytech/ink-playground' @@ -24,8 +31,8 @@ jobs: - name: Tag Docker image if: github.ref == 'refs/heads/main' && github.repository == 'paritytech/ink-playground' - run: docker tag ink-compiler:latest ${{ secrets.DOCKER_USER_NAME }}/ink-compiler + run: docker tag ink-compiler:${{ steps.version_info.outputs.latest_ink_version }} ${{ secrets.DOCKER_USER_NAME }}/ink-compiler:${{ steps.version_info.outputs.latest_ink_version }} - name: Push Docker image if: github.ref == 'refs/heads/main' && github.repository == 'paritytech/ink-playground' - run: docker push ${{ secrets.DOCKER_USER_NAME }}/ink-compiler + run: docker push ${{ secrets.DOCKER_USER_NAME }}/ink-compiler:${{ steps.version_info.outputs.latest_ink_version }} diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 5e1a7a2d4..7870f1380 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -32,8 +32,11 @@ jobs: - name: Tag Docker image run: docker tag achimcc/ink-playground:latest ink-playground + - name: Add single version to versions list (storage limitation of github actions) + run: echo "[\"4.2.0\"]" > ./config/versions.json + - name: Run docker - run: make docker-run-detach + run: DOCKER_CI_VOLUME_MOUNT="--volume ./config/versions.json:/app/config/versions.json" make docker-run-detach env: DOCKER_PORT: 4000 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 71e77bfaa..d984cf69e 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -55,8 +55,6 @@ jobs: - name: Build run: cargo build --verbose - name: Pull docker image - run: docker pull docker.io/achimcc/ink-compiler:latest - - name: Tag docker image - run: docker tag docker.io/achimcc/ink-compiler:latest ink-compiler + run: ./scripts/ink-compiler.sh -c pull_specific --specific_version 4.2.0 --docker_user_name radhezeeve - name: Run tests run: cargo test --workspace --exclude rust_analyzer_wasm --verbose diff --git a/Dockerfile b/Dockerfile index aab1f8256..5ef792ab8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -57,7 +57,15 @@ FROM base as frontend-builder RUN apt-get --yes update RUN apt-get --yes upgrade -RUN apt-get install --yes nodejs npm + +ENV NVM_DIR /usr/local/nvm +ENV NODE_VERSION v18.16.1 +RUN mkdir -p /usr/local/nvm && apt-get update && echo "y" | apt-get install curl +RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash +RUN /bin/bash -c "source $NVM_DIR/nvm.sh && nvm install $NODE_VERSION && nvm use --delete-prefix $NODE_VERSION" +ENV NODE_PATH $NVM_DIR/versions/node/$NODE_VERSION/bin +ENV PATH $NODE_PATH:$PATH + RUN npm install --global yarn RUN make install @@ -98,6 +106,8 @@ FROM debian:bullseye-slim COPY --from=frontend-builder /app/packages/playground/dist /app/packages/playground/dist COPY --from=backend-builder /app/target/release/backend /app/target/release/backend +COPY ./scripts /app/scripts +COPY ./config/versions.json /app/config/versions.json # Install Docker # see: https://www.how2shout.com/linux/install-docker-ce-on-debian-11-bullseye-linux/ @@ -117,10 +127,9 @@ RUN echo \ RUN apt-get --yes update RUN apt-get --yes install docker-ce docker-ce-cli \ - containerd.io + containerd.io jq # Provide startup scripts - COPY sysbox/on-start.sh /usr/bin RUN chmod +x /usr/bin/on-start.sh diff --git a/Makefile b/Makefile index 894602463..7016b555a 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,11 @@ FORMATTING_URL ?= http://localhost:4000/format ANALYTICS_URL ?= https://api-sa.substrate.io -DOCKER_USER_NAME ?= achimcc +VERSION_LIST_URL ?= http://localhost:4000/version_list + +DOCKER_USER_NAME ?= radhezeeve + +DOCKER_CI_VOLUME_MOUNT ?= ################################################################################ # GENERATE @@ -63,6 +67,7 @@ playground-build: GIST_LOAD_URL=/gist/load \ GIST_CREATE_URL=/gist/create \ ANALYTICS_URL=$(ANALYTICS_URL) \ + VERSION_LIST_URL=/version_list \ yarn workspace playground run build playground-start: @@ -72,6 +77,7 @@ playground-start: GIST_LOAD_URL=$(GIST_LOAD_URL) \ GIST_CREATE_URL=$(GIST_CREATE_URL) \ ANALYTICS_URL=$(ANALYTICS_URL) \ + VERSION_LIST_URL=$(VERSION_LIST_URL) \ yarn workspace playground run start playground-clean: @@ -248,6 +254,7 @@ docker-run-detach: --name ink-playground-container \ --detach \ --volume /tmp:/tmp \ + $(DOCKER_CI_VOLUME_MOUNT) \ --publish $(DOCKER_PORT):4000 \ ink-playground @@ -266,6 +273,9 @@ docker-shell: docker-log: docker logs ink-playground-container +docker-pull-images: + ./scripts/ink-compiler.sh -c pull --docker_user_name ${DOCKER_USER_NAME} + ################################################################################ # GLOBAL ################################################################################ diff --git a/README.md b/README.md index e980f3fec..87b65d4e8 100644 --- a/README.md +++ b/README.md @@ -61,15 +61,13 @@ To clone and build the whole project on your local computer, enter: 5. `make build` -Then pull and tag the docker image which is used by the backend to compile, test & format Smart Contracts: +Then pull and tag the docker images which are used by the backend to compile, test & format Smart Contracts: -6. `docker pull achimcc/ink-compiler` - -7. `docker tag achimcc/ink-compiler ink-compiler` +6. `make docker-pull-images` Finally, start the backend with: -6. `make backend-run` +7. `make backend-run` The last command starts the Rust webserver locally on your computer. You can then access `localhost:4000` from your browser to open the locally compiled ink! Playground open. diff --git a/config/versions.json b/config/versions.json new file mode 100644 index 000000000..7361c36bf --- /dev/null +++ b/config/versions.json @@ -0,0 +1 @@ +["4.3.0", "4.2.1", "4.2.0", "4.1.0", "4.0.1", "4.0.0"] diff --git a/crates/backend/src/cli.rs b/crates/backend/src/cli.rs index b526b9119..889bbb2d5 100644 --- a/crates/backend/src/cli.rs +++ b/crates/backend/src/cli.rs @@ -25,6 +25,13 @@ pub struct Opts { #[arg(short = 'f', long = "frontend_folder")] pub frontend_folder: Option, + #[arg( + long = "versions_file_path", + default_value = "./config/versions.json", + env = "VERSIONS_FILE_PATH" + )] + pub versions_file_path: String, + #[arg(short = 'g', long = "github_token", env = "GITHUB_GIST_TOKEN")] pub github_token: Option, diff --git a/crates/backend/src/main.rs b/crates/backend/src/main.rs index b6df33e7c..24e928f3d 100644 --- a/crates/backend/src/main.rs +++ b/crates/backend/src/main.rs @@ -27,11 +27,19 @@ use crate::{ FORMAT_SANDBOXED, TEST_SANDBOXED, }, - frontend::route_frontend, + frontend::{ + route_frontend, + route_frontend_version, + FrontendState, + }, gist::{ create::route_gist_create, load::route_gist_load, }, + version::{ + route_version_list, + AppVersionState, + }, }, }; use actix_cors::Cors; @@ -71,6 +79,10 @@ async fn main() -> std::io::Result<()> { } } + if !Path::new(&opts.versions_file_path.clone()).is_file() { + panic!("{} is not a valid file.", opts.versions_file_path); + } + async fn health() -> HttpResponse { HttpResponse::Ok().finish() } @@ -86,6 +98,7 @@ async fn main() -> std::io::Result<()> { HttpServer::new(move || { let opts: Opts = opts.clone(); let frontend_folder = opts.frontend_folder.clone(); + let versions_file_path = opts.versions_file_path.clone(); let mut app = App::new() .wrap(prometheus.clone()) @@ -112,6 +125,12 @@ async fn main() -> std::io::Result<()> { .route( "/status", get().to(route_status), + ) + .app_data(web::Data::new(AppVersionState { + versions_file_path, + })) + .service( + web::resource("/version_list").to(route_version_list) ); match opts.github_token { @@ -139,7 +158,12 @@ async fn main() -> std::io::Result<()> { match frontend_folder { Some(path) => { - app = app.service(route_frontend("/", path.as_ref())); + app = app + .app_data(web::Data::new(FrontendState { + frontend_folder: path.clone(), + })) + .route("/v{tail:.*}", web::get().to(route_frontend_version)) + .service(route_frontend("/", path.as_ref())); } None => { println!("Warning: Starting backend without serving static frontend files due to missing configuration.") diff --git a/crates/backend/src/services/contract.rs b/crates/backend/src/services/contract.rs index b57e2b9b8..df435521d 100644 --- a/crates/backend/src/services/contract.rs +++ b/crates/backend/src/services/contract.rs @@ -67,6 +67,7 @@ pub async fn route_compile( let compile_result = spawn_blocking(move || { compile_strategy(CompilationRequest { source: req.source.to_string(), + version: req.version.to_string(), }) }) .await @@ -103,6 +104,7 @@ pub async fn route_test( let testing_result = spawn_blocking(move || { compile_strategy(TestingRequest { source: req.source.to_string(), + version: req.version.to_string(), }) }) .await @@ -127,6 +129,7 @@ pub async fn route_format( let formatting_result = spawn_blocking(move || { formatting_strategy(FormattingRequest { source: req.source.to_string(), + version: req.version.to_string(), }) }) .await @@ -204,6 +207,7 @@ mod tests { let req = CompilationRequest { source: "foo".to_string(), + version: "4.2.0".to_string(), }; let req = test::TestRequest::post() .set_json(&req) @@ -234,6 +238,7 @@ mod tests { let req = CompilationRequest { source: "bar".to_string(), + version: "4.2.0".to_string(), }; let req = test::TestRequest::post() @@ -264,6 +269,7 @@ mod tests { let req = TestingRequest { source: "foo".to_string(), + version: "1.0.0".to_string(), }; let req = test::TestRequest::post() .set_json(&req) @@ -293,6 +299,7 @@ mod tests { let req = TestingRequest { source: "bar".to_string(), + version: "1.0.0".to_string(), }; let req = test::TestRequest::post() .set_json(&req) diff --git a/crates/backend/src/services/frontend.rs b/crates/backend/src/services/frontend.rs index 039b27567..a92982640 100644 --- a/crates/backend/src/services/frontend.rs +++ b/crates/backend/src/services/frontend.rs @@ -15,11 +15,28 @@ //! This module contains the service which serves the backend as static files. use actix_files as fs; +use actix_web::{ + web, + Result, +}; +use std::path::Path; + +pub struct FrontendState { + pub frontend_folder: String, +} pub fn route_frontend(at: &str, dir: &str) -> actix_files::Files { fs::Files::new(at, dir).index_file("index.html") } +pub async fn route_frontend_version( + data: web::Data, +) -> Result { + Ok(fs::NamedFile::open( + Path::new(&data.frontend_folder).join("index.html"), + )?) +} + #[cfg(test)] mod tests { use super::*; diff --git a/crates/backend/src/services/mod.rs b/crates/backend/src/services/mod.rs index ef0bac9a8..695a1c8be 100644 --- a/crates/backend/src/services/mod.rs +++ b/crates/backend/src/services/mod.rs @@ -20,3 +20,4 @@ pub mod contract; pub mod frontend; pub mod gist; +pub mod version; diff --git a/crates/backend/src/services/version.rs b/crates/backend/src/services/version.rs new file mode 100644 index 000000000..939522132 --- /dev/null +++ b/crates/backend/src/services/version.rs @@ -0,0 +1,39 @@ +use std::fs; + +use actix_web::{ + body::BoxBody, + web, + HttpResponse, +}; + +pub use sandbox::VersionListResult; +use serde_json::{ + json, + Value, +}; + +pub struct AppVersionState { + pub versions_file_path: String, +} + +fn read_json_file(file_path: &str) -> Result { + fs::read_to_string(file_path) +} + +pub async fn route_version_list( + data: web::Data, +) -> HttpResponse { + let versions_file_path = &data.versions_file_path; + let versions_arr_string = read_json_file(versions_file_path).unwrap(); + let versions_arr_json: Value = + serde_json::from_str(versions_arr_string.as_str()).expect("Failed to parse JSON"); + let versions_json = json!({ + "versions": versions_arr_json + }); + let versions_json_string = + serde_json::to_string_pretty(&versions_json).expect("Failed to stringify JSON"); + + HttpResponse::Ok() + .append_header(("Content-Type", "application/json")) + .body(versions_json_string) +} diff --git a/crates/generate-bindings/src/main.rs b/crates/generate-bindings/src/main.rs index 4b572e9e5..f0712179b 100644 --- a/crates/generate-bindings/src/main.rs +++ b/crates/generate-bindings/src/main.rs @@ -37,6 +37,7 @@ use backend::services::{ GistLoadResponse, }, }, + version::VersionListResult, }; use clap::Parser; use std::{ @@ -64,6 +65,7 @@ fn main() -> std::io::Result<()> { GistLoadResponse, GistCreateRequest, GistCreateResponse, + VersionListResult, ); let path = Path::new(&target); diff --git a/crates/sandbox/src/build_command.rs b/crates/sandbox/src/build_command.rs index d2da843b1..2e8321f96 100644 --- a/crates/sandbox/src/build_command.rs +++ b/crates/sandbox/src/build_command.rs @@ -27,48 +27,60 @@ use tokio::process::Command; const DOCKER_PROCESS_TIMEOUT_SOFT: Duration = Duration::from_secs(20); -const DOCKER_CONTAINER_NAME: &str = "ink-compiler"; +const DOCKER_IMAGE_BASE_NAME: &str = "ink-compiler"; const DOCKER_WORKDIR: &str = "/builds/contract/"; const DOCKER_OUTPUT: &str = "/playground-result"; -pub fn build_compile_command(input_file: &Path, output_dir: &Path) -> Command { +pub fn build_compile_command( + input_file: &Path, + output_dir: &Path, + version: &str, +) -> Command { let mut cmd = build_docker_command(input_file, Some(output_dir)); let execution_cmd = build_execution_command(); + let docker_image_name = build_docker_image_name(version); - cmd.arg(DOCKER_CONTAINER_NAME).args(&execution_cmd); + cmd.arg(docker_image_name).args(&execution_cmd); log::debug!("Compilation command is {:?}", cmd); cmd } -pub fn build_testing_command(input_file: &Path) -> Command { +pub fn build_testing_command(input_file: &Path, version: &str) -> Command { let mut cmd = build_docker_command(input_file, None); let execution_cmd = testing_execution_command(); + let docker_image_name = build_docker_image_name(version); - cmd.arg(DOCKER_CONTAINER_NAME).args(&execution_cmd); + cmd.arg(docker_image_name).args(&execution_cmd); log::debug!("Testing command is {:?}", cmd); cmd } -pub fn build_formatting_command(input_file: &Path) -> Command { +pub fn build_formatting_command(input_file: &Path, version: &str) -> Command { let mut cmd = build_docker_command(input_file, None); let execution_cmd = formatting_execution_command(); + let docker_image_name = build_docker_image_name(version); - cmd.arg(DOCKER_CONTAINER_NAME).args(&execution_cmd); + cmd.arg(docker_image_name).args(&execution_cmd); log::debug!("Formatting command is {:?}", cmd); cmd } +fn build_docker_image_name(version: &str) -> String { + let result = format!("{}:{}", DOCKER_IMAGE_BASE_NAME, version); + result +} + fn build_docker_command(input_file: &Path, output_dir: Option<&Path>) -> Command { let file_name = "lib.rs"; @@ -150,7 +162,7 @@ fn testing_execution_command() -> Vec { } fn formatting_execution_command() -> Vec { - let format_cmd = "cargo +nightly fmt && cat lib.rs 2>&1".to_string(); + let format_cmd = "cargo fmt && cat lib.rs 2>&1".to_string(); let cmd = vec!["/bin/bash".to_string(), "-c".to_string(), format_cmd]; diff --git a/crates/sandbox/src/lib.rs b/crates/sandbox/src/lib.rs index 810723d41..8212a15a2 100644 --- a/crates/sandbox/src/lib.rs +++ b/crates/sandbox/src/lib.rs @@ -120,6 +120,7 @@ pub type Result = std::result::Result; #[derive(Deserialize, Serialize, TypeDef, Debug, Clone)] pub struct CompilationRequest { pub source: String, + pub version: String, } #[derive(Deserialize, Serialize, TypeDef, PartialEq, Debug, Clone, Eq)] @@ -139,6 +140,7 @@ pub enum CompilationResult { #[derive(Deserialize, Serialize, TypeDef, Debug, Clone)] pub struct TestingRequest { pub source: String, + pub version: String, } #[derive(Deserialize, Serialize, TypeDef, PartialEq, Debug, Clone, Eq)] @@ -151,6 +153,7 @@ pub enum TestingResult { #[derive(Deserialize, Serialize, TypeDef, Debug, Clone)] pub struct FormattingRequest { pub source: String, + pub version: String, } #[derive(Deserialize, Serialize, TypeDef, PartialEq, Debug, Clone, Eq)] @@ -160,6 +163,13 @@ pub enum FormattingResult { Error { stdout: String, stderr: String }, } +#[derive(Deserialize, Serialize, TypeDef, PartialEq, Debug, Clone, Eq)] +#[serde(rename_all = "snake_case")] +// #[serde(tag = "type", content = "payload", rename_all = "SCREAMING_SNAKE_CASE")] +pub struct VersionListResult { + versions: Vec, +} + // ------------------------------------------------------------------------------------------------- // CONSTANTS // ------------------------------------------------------------------------------------------------- @@ -191,8 +201,8 @@ impl Sandbox { pub fn compile(&self, req: &CompilationRequest) -> Result { self.write_source_code(&req.source)?; - let command = build_compile_command(&self.input_file, &self.output_dir); - + let command = + build_compile_command(&self.input_file, &self.output_dir, &req.version); println!("Executing command: \n{:?}", command); let output = run_command_with_timeout(command)?; @@ -228,7 +238,7 @@ impl Sandbox { pub fn test(&self, req: &TestingRequest) -> Result { self.write_source_code(&req.source)?; - let command = build_testing_command(&self.input_file); + let command = build_testing_command(&self.input_file, &req.version); println!("Executing command: \n{:?}", command); @@ -245,7 +255,7 @@ impl Sandbox { pub fn format(&self, req: &FormattingRequest) -> Result { self.write_source_code(&req.source)?; - let command = build_formatting_command(&self.input_file); + let command = build_formatting_command(&self.input_file, &req.version); println!("Executing command: \n{:?}", command); @@ -386,9 +396,9 @@ fn vec_to_str(v: Vec) -> Result { mod tests { use super::*; - fn compile_check(source: String) -> Option { + fn compile_check(source: String, version: String) -> Option { Sandbox::new() - .and_then(|sandbox| sandbox.compile(&CompilationRequest { source })) + .and_then(|sandbox| sandbox.compile(&CompilationRequest { source, version })) .map(|result| { match result { CompilationResult::Success { @@ -408,14 +418,14 @@ mod tests { #[test] fn test_compile_valid_code() { let flipper_code = include_str!("../../contract/lib.rs"); - let actual_result = compile_check(flipper_code.to_string()); + let actual_result = compile_check(flipper_code.to_string(), "4.2.0".to_string()); assert_eq!(actual_result, Some(true)) } #[test] fn test_compile_invalid_code() { - let actual_result = compile_check("".to_string()); + let actual_result = compile_check("".to_string(), "4.2.0".to_string()); assert_eq!(actual_result, Some(false)) } diff --git a/docker/Dockerfile.compiler-4.0.0 b/docker/Dockerfile.compiler-4.0.0 new file mode 100644 index 000000000..7a46eb191 --- /dev/null +++ b/docker/Dockerfile.compiler-4.0.0 @@ -0,0 +1,36 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/ink-ci-linux:latest +FROM ${REGISTRY_PATH}/ink-ci-linux:ee3f4073-20230720 +# ARG RUST_NIGHTLY="2023-06-01" +# ARG RUST_VERSION="1.69.0" + +RUN cargo install --force --locked cargo-contract --version 2.0.1 +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.0.0" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} +RUN cd contract && cargo update -p contract-build --precise 2.0.1 +RUN cd contract && cargo update -p clap --precise 4.1.6 +RUN cd contract && cargo update -p colored --precise 2.0.4 +RUN cd contract && cargo update -p parity-scale-codec --precise 3.6.1 + +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/docker/Dockerfile.compiler-4.0.1 b/docker/Dockerfile.compiler-4.0.1 new file mode 100644 index 000000000..e46239f81 --- /dev/null +++ b/docker/Dockerfile.compiler-4.0.1 @@ -0,0 +1,49 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/base-ci-linux:latest +FROM ${REGISTRY_PATH}/base-ci-linux:ee3f4073-20230720 +ARG RUST_NIGHTLY="2023-06-01" +ARG RUST_VERSION="1.69.0" + +WORKDIR /builds + +RUN set -eux; \ + rustup install ${RUST_VERSION} && \ + rustup default ${RUST_VERSION} && \ + rustup toolchain install ${RUST_VERSION} && \ + rustup target add wasm32-unknown-unknown --toolchain ${RUST_VERSION} && \ + rustup component add rust-src --toolchain ${RUST_VERSION} && \ + rustup component add rustfmt --toolchain ${RUST_VERSION} + +RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +ARG CRAGO_CONTRACT_VERSION="2.1.0" + +RUN cargo install --force --locked cargo-contract --version ${CRAGO_CONTRACT_VERSION} +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.0.1" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} +RUN cd contract && cargo update -p contract-build --precise ${CRAGO_CONTRACT_VERSION} +RUN cd contract && cargo update -p colored --precise 2.0.4 +RUN cd contract && cargo update -p clap --precise 4.1.8 + +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/docker/Dockerfile.compiler-4.1.0 b/docker/Dockerfile.compiler-4.1.0 new file mode 100644 index 000000000..643dca01d --- /dev/null +++ b/docker/Dockerfile.compiler-4.1.0 @@ -0,0 +1,49 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/base-ci-linux:latest +FROM ${REGISTRY_PATH}/base-ci-linux:ee3f4073-20230720 +ARG RUST_NIGHTLY="2023-06-01" +ARG RUST_VERSION="1.69.0" + +WORKDIR /builds + +RUN set -eux; \ + rustup install ${RUST_VERSION} && \ + rustup default ${RUST_VERSION} && \ + rustup toolchain install ${RUST_VERSION} && \ + rustup target add wasm32-unknown-unknown --toolchain ${RUST_VERSION} && \ + rustup component add rust-src --toolchain ${RUST_VERSION} && \ + rustup component add rustfmt --toolchain ${RUST_VERSION} + +RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +ARG CRAGO_CONTRACT_VERSION="2.1.0" + +RUN cargo install --force --locked cargo-contract --version ${CRAGO_CONTRACT_VERSION} +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.1.0" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} +RUN cd contract && cargo update -p contract-build --precise 2.0.2 +RUN cd contract && cargo update -p colored --precise 2.0.4 +RUN cd contract && cargo update -p clap --precise 4.1.8 + +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/docker/Dockerfile.compiler-4.2.0 b/docker/Dockerfile.compiler-4.2.0 new file mode 100644 index 000000000..60d4d6d38 --- /dev/null +++ b/docker/Dockerfile.compiler-4.2.0 @@ -0,0 +1,45 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/base-ci-linux:latest +FROM ${REGISTRY_PATH}/base-ci-linux:ee3f4073-20230720 +ARG RUST_NIGHTLY="2023-06-01" +ARG RUST_VERSION="1.73.0" + +WORKDIR /builds + +RUN set -eux; \ + rustup install ${RUST_VERSION} && \ + rustup default ${RUST_VERSION} && \ + rustup toolchain install ${RUST_VERSION} && \ + rustup target add wasm32-unknown-unknown --toolchain ${RUST_VERSION} && \ + rustup component add rust-src --toolchain ${RUST_VERSION} && \ + rustup component add rustfmt --toolchain ${RUST_VERSION} + +RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +ARG CRAGO_CONTRACT_VERSION="3.2.0" +RUN cargo install --force --locked cargo-contract --version ${CRAGO_CONTRACT_VERSION} +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.2.0" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} +RUN cd contract && cargo update -p contract-build --precise 2.0.2 +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/docker/Dockerfile.compiler-4.2.1 b/docker/Dockerfile.compiler-4.2.1 new file mode 100644 index 000000000..b5de111a2 --- /dev/null +++ b/docker/Dockerfile.compiler-4.2.1 @@ -0,0 +1,46 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/base-ci-linux:latest +FROM ${REGISTRY_PATH}/base-ci-linux:ee3f4073-20230720 +ARG RUST_NIGHTLY="2023-06-01" +ARG RUST_VERSION="1.73.0" + +WORKDIR /builds + +RUN set -eux; \ + rustup install ${RUST_VERSION} && \ + rustup default ${RUST_VERSION} && \ + rustup toolchain install ${RUST_VERSION} && \ + rustup target add wasm32-unknown-unknown --toolchain ${RUST_VERSION} && \ + rustup component add rust-src --toolchain ${RUST_VERSION} && \ + rustup component add rustfmt --toolchain ${RUST_VERSION} + +RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +ARG CRAGO_CONTRACT_VERSION="3.2.0" +RUN cargo install --force --locked cargo-contract --version ${CRAGO_CONTRACT_VERSION} +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.2.1" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} +RUN cd contract && cargo update -p contract-build --precise 2.0.2 + +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/docker/Dockerfile.compiler-4.3.0 b/docker/Dockerfile.compiler-4.3.0 new file mode 100644 index 000000000..99107d80a --- /dev/null +++ b/docker/Dockerfile.compiler-4.3.0 @@ -0,0 +1,45 @@ +ARG REGISTRY_PATH=docker.io/paritytech + +# paritytech/base-ci-linux:latest +FROM ${REGISTRY_PATH}/base-ci-linux:ee3f4073-20230720 +ARG RUST_NIGHTLY="2023-06-01" +ARG RUST_VERSION="1.73.0" + +WORKDIR /builds + +RUN set -eux; \ + rustup install ${RUST_VERSION} && \ + rustup default ${RUST_VERSION} && \ + rustup toolchain install ${RUST_VERSION} && \ + rustup target add wasm32-unknown-unknown --toolchain ${RUST_VERSION} && \ + rustup component add rust-src --toolchain ${RUST_VERSION} && \ + rustup component add rustfmt --toolchain ${RUST_VERSION} + +RUN curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh + +ARG CRAGO_CONTRACT_VERSION="3.2.0" +RUN cargo install --force --locked cargo-contract --version ${CRAGO_CONTRACT_VERSION} +ENV CARGO_TARGET_DIR="/target" +RUN cargo contract new contract + +ARG INK_VERSION="4.3.0" + +RUN cd contract && cargo update -p ink_e2e --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_env --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_e2e_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_macro --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_codegen --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_ir --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_engine --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_storage_traits --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_metadata --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_primitives --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_allocator --precise ${INK_VERSION} +RUN cd contract && cargo update -p ink_prelude --precise ${INK_VERSION} + +RUN cd contract && cargo contract build +RUN cd contract && cargo test + +WORKDIR /builds/contract \ No newline at end of file diff --git a/packages/components/src/MenuSelectElementWrapper.tsx b/packages/components/src/MenuSelectElementWrapper.tsx new file mode 100644 index 000000000..3b4939960 --- /dev/null +++ b/packages/components/src/MenuSelectElementWrapper.tsx @@ -0,0 +1,19 @@ +import { ReactElement, ReactNode, MouseEvent } from 'react'; + +export type Props = { + children: ReactNode; + onClick: ( + e?: MouseEvent + ) => void | Promise | null; +}; + +export const MenuSelectElementWrapper = ({ children, onClick }: Props): ReactElement => { + return ( + + ); +}; diff --git a/packages/components/src/index.tsx b/packages/components/src/index.tsx index 6dc4681e8..8de0cdee8 100644 --- a/packages/components/src/index.tsx +++ b/packages/components/src/index.tsx @@ -14,3 +14,4 @@ export { Severity } from './console/ConsoleMessage'; export type { Message, Prompt, Status, SeverityColors } from './console/ConsoleMessage'; export { LabeledLink } from './LabeledLink'; export { MenuElementWrapper } from './MenuElementWrapper'; +export { MenuSelectElementWrapper } from './MenuSelectElementWrapper'; diff --git a/packages/docker-tests/__tests__/docker.test.ts b/packages/docker-tests/__tests__/docker.test.ts index e1f472fb2..270c984dd 100644 --- a/packages/docker-tests/__tests__/docker.test.ts +++ b/packages/docker-tests/__tests__/docker.test.ts @@ -30,6 +30,7 @@ describe('Given the server provides a working compile endpoint', () => { await expect( axios.post(`${BACKEND_URL}/compile`, { source, + version: '4.2.0', }) ).resolves.toMatchObject({ status: 200, data: { type: 'SUCCESS' } }); }); diff --git a/packages/ink-editor/src/api/version.ts b/packages/ink-editor/src/api/version.ts new file mode 100644 index 000000000..969eada93 --- /dev/null +++ b/packages/ink-editor/src/api/version.ts @@ -0,0 +1,42 @@ +import Common from '@paritytech/commontypes'; + +export type versionListApiResponse = + | { + type: 'OK'; + payload: Common.VersionListResult; + } + | { + type: 'NETWORK_ERROR'; + } + | { + type: 'SERVER_ERROR'; + payload: { status: number }; + }; + +export type Config = { + versionListUrl: string; +}; + +const mapResponse = async (response: Response): Promise => + response.status === 200 + ? { + type: 'OK', + payload: await response.json(), + } + : { + type: 'SERVER_ERROR', + payload: { status: response.status }, + }; + +export const versionListRequest = (config: Config): Promise => { + const opts: RequestInit = { + method: 'GET', + mode: 'cors', + credentials: 'same-origin', + headers: { 'Content-Type': 'application/json' }, + }; + + return fetch(config.versionListUrl || '', opts) + .then(mapResponse) + .catch(() => ({ type: 'NETWORK_ERROR' })); +}; diff --git a/packages/playground/package.json b/packages/playground/package.json index ec4a6babf..7d1d19de3 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -11,6 +11,7 @@ "react": "^18.2.0", "react-dom": "^18.2.0", "react-monaco-editor": "^0.49.0", + "react-router-dom": "^6.17.0", "use-reducer-logger": "^1.0.2" }, "scripts": { diff --git a/packages/playground/src/app/Header/VersionsSubmenu.tsx b/packages/playground/src/app/Header/VersionsSubmenu.tsx new file mode 100644 index 000000000..358a50d25 --- /dev/null +++ b/packages/playground/src/app/Header/VersionsSubmenu.tsx @@ -0,0 +1,24 @@ +import { MenuSelectElementWrapper } from '@paritytech/components/'; +import { ReactElement, useContext } from 'react'; +import { AppContext } from '~/context/app/'; +import { Dispatch, State } from '~/context/app/reducer'; +import { setVersion } from '~/context/side-effects/version'; + +export const VersionsSubmenu = (): ReactElement => { + const [state, dispatch]: [State, Dispatch] = useContext(AppContext); + + return ( +
+

Supported Versions

+ {state.versionList.map(version => ( + { + setVersion(version, state, { app: dispatch }); + }} + > + {version} {state.version === version ? '- Active' : ''} + + ))} +
+ ); +}; diff --git a/packages/playground/src/app/Header/index.tsx b/packages/playground/src/app/Header/index.tsx index c1452431b..6bffb4931 100644 --- a/packages/playground/src/app/Header/index.tsx +++ b/packages/playground/src/app/Header/index.tsx @@ -13,6 +13,7 @@ import { } from '~/symbols'; import { OverlayPanel, ButtonWithIcon } from '@paritytech/components/'; import { SettingsSubmenu } from './SettingsSubmenu'; +import { VersionsSubmenu } from './VersionsSubmenu'; import { ShareSubmenu } from './ShareSubmenu'; import { AppContext } from '~/context/app/'; @@ -54,6 +55,7 @@ export const Header = (): ReactElement => { const [, dispatchMessage]: [MessageState, MessageDispatch] = useContext(MessageContext); const settingsOverlay = useRef(null); + const versionsOverlay = useRef(null); const shareOverlay = useRef(null); const hasDownloadableResult = @@ -121,6 +123,14 @@ export const Header = (): ReactElement => { onClick={e => settingsOverlay.current && settingsOverlay.current.toggle(e, null)} /> + versionsOverlay.current && versionsOverlay.current.toggle(e, null)} + /> +
{ + + + diff --git a/packages/playground/src/app/index.tsx b/packages/playground/src/app/index.tsx index a6947dd59..e30fb1ea9 100644 --- a/packages/playground/src/app/index.tsx +++ b/packages/playground/src/app/index.tsx @@ -8,19 +8,64 @@ import { ReactElement, useContext, useEffect } from 'react'; import { Dispatch, State } from '~/context/app/reducer'; import { MessageDispatch, MessageState } from '~/context/messages/reducer'; import { loadCode } from '~/context/side-effects/load-code'; +import { loadVersionList, setVersion } from '~/context/side-effects/version'; import { monaco } from 'react-monaco-editor'; +import { + Routes, + Route, + useNavigate, + BrowserRouter, + useParams, + useSearchParams, +} from 'react-router-dom'; const App = (): ReactElement => { const [state, dispatch]: [State, Dispatch] = useContext(AppContext); const [, messageDispatch]: [MessageState, MessageDispatch] = useContext(MessageContext); + const [searchParams, setSearchParams] = useSearchParams(); + const { versionParam } = useParams(); + const navigate = useNavigate(); + const { monacoUri: uri, formatting } = state; + const navigateVersion = (version: string) => { + navigate(`/v${version}`); + }; + + useEffect(() => { + if (state.version && versionParam != `v${state.version}`) { + navigateVersion(state.version); + } + }, [state.version]); + + useEffect(() => { + if ( + versionParam?.startsWith('v') && + state.versionList.includes(versionParam?.replace('v', '')) + ) { + setVersion(versionParam?.replace('v', ''), state, { app: dispatch }); + } else if (state.versionList.length > 0 && state.versionList[0]) { + setVersion(state.versionList[0], state, { app: dispatch }); + navigateVersion(state.versionList[0]); + } + }, [state.versionList]); + useEffect(() => { + const searchParamCode = searchParams.get('code'); if (!uri) return; loadCode(state, { app: dispatch, message: messageDispatch }).then(code => { const model = monaco.editor.getModel(uri as monaco.Uri); if (!model) return; - model.setValue(code); + model.setValue(searchParamCode ?? code); + if (searchParamCode) + setSearchParams(oldSearchParams => { + oldSearchParams.delete('code'); + return oldSearchParams; + }); + }); + loadVersionList(state, { app: dispatch }).then(() => { + const version = versionParam ? versionParam?.replace('v', '') : ''; + setVersion(version, state, { app: dispatch }); }); }, [uri]); @@ -54,31 +99,39 @@ const App = (): ReactElement => { }; return ( - } - editor={ - dispatch({ type: 'SET_URI', payload: uri })} - /> - } - console={} - /> + <> +

{versionParam}

+ } + editor={ + dispatch({ type: 'SET_URI', payload: uri })} + /> + } + console={} + /> + ); }; const AppWithProvider = (): ReactElement => { return ( - - - - - + + + + + } /> + } /> + + + + ); }; diff --git a/packages/playground/src/context/app/reducer.ts b/packages/playground/src/context/app/reducer.ts index 01567faf3..90f191ec9 100644 --- a/packages/playground/src/context/app/reducer.ts +++ b/packages/playground/src/context/app/reducer.ts @@ -15,6 +15,8 @@ export const defaultState: State = { gist: { type: 'NOT_ASKED' }, contractSize: null, rustAnalyzer: false, + versionList: [], + version: '', }; export type State = { @@ -28,6 +30,8 @@ export type State = { gist: GistState; contractSize: number | null; rustAnalyzer: boolean; + versionList: string[]; + version: string; }; export type GistState = @@ -60,7 +64,9 @@ export type Action = | { type: 'SET_GIST_STATE'; payload: GistState } | { type: 'SET_URI'; payload: Uri } | { type: 'SET_CONTRACT_SIZE'; payload: number | null } - | { type: 'SET_RUST_ANALYZER_STATE'; payload: boolean }; + | { type: 'SET_RUST_ANALYZER_STATE'; payload: boolean } + | { type: 'SET_VERSIONS_STATE'; payload: string[] } + | { type: 'SET_VERSION_STATE'; payload: string }; export type Dispatch = (action: Action) => void; @@ -116,6 +122,16 @@ export const reducer = (state: State, action: Action): State => { ...state, contractSize: action.payload, }; + case 'SET_VERSIONS_STATE': + return { + ...state, + versionList: action.payload, + }; + case 'SET_VERSION_STATE': + return { + ...state, + version: action.payload, + }; default: return state; } diff --git a/packages/playground/src/context/side-effects/compile.ts b/packages/playground/src/context/side-effects/compile.ts index 061fb39f6..3931e3bbc 100644 --- a/packages/playground/src/context/side-effects/compile.ts +++ b/packages/playground/src/context/side-effects/compile.ts @@ -82,7 +82,10 @@ export async function compile(state: State, dispatch: Dispatch, dispatchMessage: const code = model.getValue(); - const result = await compileRequest({ compileUrl: COMPILE_URL || '' }, { source: code }); + const result = await compileRequest( + { compileUrl: COMPILE_URL || '' }, + { source: code, version: state.version } + ); dispatch({ type: 'SET_COMPILE_STATE', diff --git a/packages/playground/src/context/side-effects/format.ts b/packages/playground/src/context/side-effects/format.ts index 0b290488b..4c588b1b9 100644 --- a/packages/playground/src/context/side-effects/format.ts +++ b/packages/playground/src/context/side-effects/format.ts @@ -103,7 +103,7 @@ export async function format(state: State, dispatch: Dispatch, dispatchMessage: const result = await formattingRequest( { compileUrl: FORMATTING_URL || '' }, - { source: code } + { source: code, version: state.version } ).then(interpret_response); dispatch({ diff --git a/packages/playground/src/context/side-effects/testing.ts b/packages/playground/src/context/side-effects/testing.ts index 85da0ec8f..fe2ca717e 100644 --- a/packages/playground/src/context/side-effects/testing.ts +++ b/packages/playground/src/context/side-effects/testing.ts @@ -97,9 +97,10 @@ export async function testing(state: State, dispatch: Dispatch, dispatchMessage: const code = model.getValue(); - const result = await testingRequest({ compileUrl: TESTING_URL || '' }, { source: code }).then( - interpret_response - ); + const result = await testingRequest( + { compileUrl: TESTING_URL || '' }, + { source: code, version: state.version } + ).then(interpret_response); dispatch({ type: 'SET_TESTING_STATE', diff --git a/packages/playground/src/context/side-effects/version.ts b/packages/playground/src/context/side-effects/version.ts new file mode 100644 index 000000000..763718fbf --- /dev/null +++ b/packages/playground/src/context/side-effects/version.ts @@ -0,0 +1,35 @@ +import { versionListRequest } from '@paritytech/ink-editor/api/version'; +import { State, Dispatch as AppDispatch } from '~/context/app/reducer'; +import { VERSION_LIST_URL } from '~/env'; + +type Dispatch = { + app: AppDispatch; +}; + +export async function loadVersionList(state: State, dispatch: Dispatch) { + const { versionList: versions } = state; + const result = await versionListRequest({ versionListUrl: VERSION_LIST_URL || '' }); + if (result.type === 'OK') { + dispatch.app({ + type: 'SET_VERSIONS_STATE', + payload: result.payload.versions, + }); + } else { + dispatch.app({ + type: 'SET_VERSIONS_STATE', + payload: versions, + }); + } +} + +export async function setVersion(version: string, state: State, dispatch: Dispatch) { + const { versionList: versions } = state; + if (!version) { + version = versions.length > 0 && versions[0] ? versions[0] : ''; + } + + dispatch.app({ + type: 'SET_VERSION_STATE', + payload: version, + }); +} diff --git a/packages/playground/src/env.ts b/packages/playground/src/env.ts index dd02f3007..841f38d45 100644 --- a/packages/playground/src/env.ts +++ b/packages/playground/src/env.ts @@ -8,4 +8,6 @@ export const GIST_CREATE_URL: string | undefined = process.env.GIST_CREATE_URL; export const GIST_LOAD_URL: string | undefined = process.env.GIST_LOAD_URL; +export const VERSION_LIST_URL: string | undefined = process.env.VERSION_LIST_URL; + export const NODE_ENV = process.env.NODE_ENV as 'production' | 'development'; diff --git a/packages/playground/webpack.config.js b/packages/playground/webpack.config.js index b71251340..0a8b8d9b2 100644 --- a/packages/playground/webpack.config.js +++ b/packages/playground/webpack.config.js @@ -19,6 +19,7 @@ const localConfig = { output: { filename: 'bundle.[fullhash].js', path: path.resolve(__dirname, 'dist'), + publicPath: '/', }, resolve: { extensions: ['.ts', '.tsx', '.js', '.jsx', '.wasm', '.css'], @@ -75,6 +76,7 @@ const localConfig = { FORMATTING_URL: '', GIST_CREATE_URL: '', GIST_LOAD_URL: '', + VERSION_LIST_URL: '', }), new webpack.ProvidePlugin({ process: 'process/browser', @@ -94,6 +96,9 @@ const localConfig = { warnings: false, }, }, + historyApiFallback: { + disableDotRule: true, + }, }, }; diff --git a/rustfmt.toml b/rustfmt.toml index 25a156b64..29528533b 100644 --- a/rustfmt.toml +++ b/rustfmt.toml @@ -35,7 +35,7 @@ struct_field_align_threshold = 0 enum_discrim_align_threshold = 0 match_arm_blocks = true force_multiline_blocks = true # changed -fn_args_layout = "Tall" +fn_params_layout = "Tall" brace_style = "SameLineWhere" control_brace_style = "AlwaysSameLine" trailing_semicolon = false # changed diff --git a/scripts/ink-compiler.sh b/scripts/ink-compiler.sh new file mode 100755 index 000000000..b72b48453 --- /dev/null +++ b/scripts/ink-compiler.sh @@ -0,0 +1,126 @@ +#!/bin/bash + + +set -eu +set -o pipefail +set -o nounset + +command="" +docker_user_name="" +specific_version="" + +relative_dirname="$(dirname -- "${BASH_SOURCE[0]}")" +bash_dir_path="$(cd -- "${relative_dirname}" && pwd)" + +pull() { + versions=($(cat ${bash_dir_path}/../config/versions.json | jq -r '.[]')) + for version in "${versions[@]}"; do + docker pull ${docker_user_name}/ink-compiler:${version} + docker tag ${docker_user_name}/ink-compiler:${version} ink-compiler:${version} + done +} + + +build() { + versions=($(cat ${bash_dir_path}/../config/versions.json | jq -r '.[]')) + cd ${bash_dir_path}/../docker + for version in "${versions[@]}"; do + docker build --tag ink-compiler:${version} -f Dockerfile.compiler-${version} . + done +} + +push() { + versions=($(cat ${bash_dir_path}/../config/versions.json | jq -r '.[]')) + for version in "${versions[@]}"; do + docker tag ink-compiler:${version} ${docker_user_name}/ink-compiler:${version} + docker push ${docker_user_name}/ink-compiler:${version} + done +} + +build_specific() { + cd ${bash_dir_path}/../docker + docker build --tag ink-compiler:${specific_version} -f Dockerfile.compiler-${specific_version} . +} + +pull_specific() { + docker pull ${docker_user_name}/ink-compiler:${specific_version} + docker tag ${docker_user_name}/ink-compiler:${specific_version} ink-compiler:${specific_version} +} + +push_specific() { + docker tag ink-compiler:${specific_version} ${docker_user_name}/ink-compiler:${specific_version} + docker push ${docker_user_name}/ink-compiler:${specific_version} +} + +usage() { + echo "USAGE" + echo "Execute docker related commands" + echo "options:" + echo "-c --command : command to execute (pull, build, push, build_specific, push_specific)" + echo "--docker_user_name : docker image to pull and push from)" + echo "--specific_version : ink specific version, used to build, pull and push specific ink compiler image)" +} + +check_blank_args() { + if [ -z "${1:-}" ]; then + echo "Arguments are not passed correctly, refer the following:" + usage; + exit 1; + fi +} + +while [ "$#" -ge 1 ]; do + case "$1" in + -c|--command) + shift; + check_blank_args "${1:-}" + command=$1 + ;; + --docker_user_name) + shift; + check_blank_args "${1:-}" + docker_user_name=$1 + ;; + --specific_version) + shift; + check_blank_args "${1:-}" + specific_version=$1 + ;; + *) + usage; + exit 1 + ;; + esac; + shift; +done; + +case ${command} in + "pull") + pull + ;; + + "build") + build + ;; + + "push") + push + ;; + + "pull_specific") + pull_specific + ;; + + "build_specific") + build_specific + ;; + + "push_specific") + push_specific + ;; + + *) + echo "wrong command" + exit 1; + ;; +esac diff --git a/sysbox/on-start.sh b/sysbox/on-start.sh index 40c2bf055..0a754d776 100755 --- a/sysbox/on-start.sh +++ b/sysbox/on-start.sh @@ -1,13 +1,11 @@ -#!/bin/sh +#!/bin/bash # dockerd start dockerd > /var/log/dockerd.log 2>&1 & sleep 2 # pull inner images -docker pull achimcc/ink-compiler:latest -docker tag achimcc/ink-compiler ink-compiler +/app/scripts/ink-compiler.sh -c pull --docker_user_name radhezeeve # start backend server -/app/target/release/backend --port 4000 --host 0.0.0.0 --frontend_folder /app/packages/playground/dist - +/app/target/release/backend --port 4000 --host 0.0.0.0 --frontend_folder /app/packages/playground/dist --versions_file_path /app/config/versions.json diff --git a/yarn.lock b/yarn.lock index e8417fecc..4642a580c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2725,6 +2725,13 @@ __metadata: languageName: node linkType: hard +"@remix-run/router@npm:1.10.0": + version: 1.10.0 + resolution: "@remix-run/router@npm:1.10.0" + checksum: f8f9fcd5f08465a7e0a05378398ff6df2c5c5ef5766df3490a134d64260b3b16f1bd490bb0c3f5925c2671a0c1d8d1fa01dfbdc7ecc3b2447dc6eafe6b73bcc2 + languageName: node + linkType: hard + "@sinclair/typebox@npm:^0.24.1": version: 0.24.51 resolution: "@sinclair/typebox@npm:0.24.51" @@ -9672,6 +9679,7 @@ __metadata: react: ^18.2.0 react-dom: ^18.2.0 react-monaco-editor: ^0.49.0 + react-router-dom: ^6.17.0 remove: ^0.1.5 rimraf: ^3.0.2 tailwindcss: ^3.0.24 @@ -10603,6 +10611,30 @@ __metadata: languageName: node linkType: hard +"react-router-dom@npm:^6.17.0": + version: 6.17.0 + resolution: "react-router-dom@npm:6.17.0" + dependencies: + "@remix-run/router": 1.10.0 + react-router: 6.17.0 + peerDependencies: + react: ">=16.8" + react-dom: ">=16.8" + checksum: e0ba4f4c507681e2ffdecdf2e67edf7ec0e2bf4be35222e29d013afdb03866a5e6ecacc8b452bd55797b9672785d02f81bd6dbf6b05ac93a59e48e774b0060de + languageName: node + linkType: hard + +"react-router@npm:6.17.0": + version: 6.17.0 + resolution: "react-router@npm:6.17.0" + dependencies: + "@remix-run/router": 1.10.0 + peerDependencies: + react: ">=16.8" + checksum: 99c30d94fbb34657e4c8c3ef1aaae33b143167d3869b442e06c83b4006f35200fde810029180e209654bef2f47f0b27a928f77cc2d859a358a2722cc9d494f03 + languageName: node + linkType: hard + "react-transition-group@npm:^4.4.1": version: 4.4.2 resolution: "react-transition-group@npm:4.4.2"