From 63b870de697a52baba0c23e3c7e36528e30b4cdc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20M=C3=BCller?= Date: Tue, 15 Mar 2022 11:12:10 +0100 Subject: [PATCH] Include `ink_linting` folder in releases + Test publish/install in CI (#463) * Include `ink_linting` folder in releases * Add CI stage to test if publishing/installing works * Revert me: Skip most CI stages * Remove unneeded `--registry` * Revert "Revert me: Skip most CI stages" This reverts commit da134108a62ebb0e6ff38f613f138d3a7063c5f3. * Make CI code clearer * Remove superfluous newline * Improve comments * Refactor `build.rs` * Add comment * Add missing argument --- .gitlab-ci.yml | 24 ++++++++++ Cargo.toml | 7 ++- build.rs | 63 +++++++++++++++---------- ink_linting/{Cargo.toml => _Cargo.toml} | 0 4 files changed, 69 insertions(+), 25 deletions(-) rename ink_linting/{Cargo.toml => _Cargo.toml} (100%) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0129a27b1..e04655be7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -87,6 +87,7 @@ test-dylint: <<: *docker-env script: - cd ink_linting/ + - mv _Cargo.toml Cargo.toml # Installing these components here is necessary because # `ink_linting/` has a fixed `rust-toolchain` file. @@ -131,6 +132,29 @@ test-new-project-template: - cargo fmt --verbose --all -- --check - cargo clippy --verbose --manifest-path Cargo.toml -- -D warnings; +# With the introduction of `ink_linting` in `build.rs` the installation process +# is more elaborate now and as part of it the `ink_linting` crate is built locally. +# We introduced this CI job to make sure that publishing to a registry and installing +# from it will work correctly. +test-registry-publish-install: + stage: test + <<: *docker-env + before_script: + # Set up a local registry. + - mkdir -p ./estuary/crates/ ./estuary/indices/ + - estuary --base-url=http://0.0.0.0:7878 --crate-dir ./estuary/crates/ --index-dir ./estuary/indices & + - mkdir .cargo + - echo -e '[registries]\nestuary = { index = "http://0.0.0.0:7878/git/index" }' > .cargo/config.toml + - echo 0000 | cargo login --registry estuary + script: + - cargo publish --registry estuary + - cargo install cargo-contract --index http://0.0.0.0:7878/git/index + + # Simple smoke testing to check if basic `check` functionality works. + - cargo run -- contract new new_project + - echo "[workspace]" >> new_project/Cargo.toml + - cargo run --all-features -- contract check --manifest-path new_project/Cargo.toml + #### stage: build (default features) build: diff --git a/Cargo.toml b/Cargo.toml index 52a82c700..b200d895b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,12 @@ homepage = "https://www.parity.io/" description = "Setup and deployment tool for developing Wasm based smart contracts via ink!" keywords = ["wasm", "parity", "webassembly", "blockchain", "edsl"] categories = ["command-line-utilities", "development-tools::build-utils", "development-tools::cargo-plugins"] -include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE", "build.rs", "templates", "src/**/*.scale"] +include = [ + "Cargo.toml", "src/**/*.rs", "README.md", "LICENSE", "build.rs", "templates", "src/**/*.scale", + # We need to include `ink_linting` in the releases, so that the dylint driver which + # is contained in that crate is build locally as part of the installation. + "ink_linting", "!ink_linting/target/", "!ink_linting/ui/" +] [dependencies] env_logger = "0.9.0" diff --git a/build.rs b/build.rs index f7085a3bc..23b087111 100644 --- a/build.rs +++ b/build.rs @@ -68,9 +68,43 @@ fn zip_template_and_build_dylint_driver(manifest_dir: PathBuf, out_dir: PathBuf) // `libink_linting@nightly-2021-11-04-x86_64-unknown-linux-gnu.so`. This file is obtained // by building the crate in `ink_linting/`. let dylint_driver_dst_file = out_dir.join("ink-dylint-driver.zip"); - build_and_zip_dylint_driver(manifest_dir, out_dir, dylint_driver_dst_file)?; - Ok(()) + let ink_dylint_driver_dir = manifest_dir.join("ink_linting"); + + // The `ink_linting/Cargo.toml` file is named `_Cargo.toml` in the repository. + // This is because we need to have the `ink_linting` folder part of the release, + // so that when somebody installs `cargo-contract` the `ink_linting` crate is + // build locally as part of that installation process. + // But if the file were named `Cargo.toml` then `cargo publish` would ignore + // the whole `ink_linting` folder and we wouldn't be able to specify the folder + // in the `cargo-contract/Cargo.toml` section of `[include]`. + // + // This is intended behavior: + // + // > Regardless of whether exclude or include is specified, the following files are always excluded: + // > * Any sub-packages will be skipped (any subdirectory that contains a Cargo.toml file). + // + // (from https://doc.rust-lang.org/cargo/reference/manifest.html#the-exclude-and-include-fields) + std::fs::rename( + ink_dylint_driver_dir.join("_Cargo.toml"), + ink_dylint_driver_dir.join("Cargo.toml"), + )?; + + let res = build_and_zip_dylint_driver( + ink_dylint_driver_dir.clone(), + out_dir, + dylint_driver_dst_file, + ); + + // After the build process of `ink_linting` happened we need to name back to the original + // `_Cargo.toml` name, otherwise the directory would be "dirty" and `cargo publish` would + // fail with `Source directory was modified by build.rs during cargo publish`. + std::fs::rename( + ink_dylint_driver_dir.join("Cargo.toml"), + ink_dylint_driver_dir.join("_Cargo.toml"), + )?; + + res } /// Creates a zip archive `template.zip` of the `new` project template in `out_dir`. @@ -95,7 +129,7 @@ fn zip_template(manifest_dir: &Path, out_dir: &Path) -> Result<()> { /// linting rules. #[cfg(feature = "cargo-clippy")] fn build_and_zip_dylint_driver( - _manifest_dir: PathBuf, + _ink_dylint_driver_dir: PathBuf, _out_dir: PathBuf, dylint_driver_dst_file: PathBuf, ) -> Result<()> { @@ -118,29 +152,10 @@ fn build_and_zip_dylint_driver( /// linting rules. #[cfg(not(feature = "cargo-clippy"))] fn build_and_zip_dylint_driver( - manifest_dir: PathBuf, + ink_dylint_driver_dir: PathBuf, out_dir: PathBuf, dylint_driver_dst_file: PathBuf, ) -> Result<()> { - let mut ink_dylint_driver_dir = manifest_dir.join("ink_linting"); - - // The following condition acocunts for the case when `cargo package` or - // `cargo publish` is used. In that case the `CARGO_MANIFEST_DIR` is actually - // of the form `cargo-contract/target/package/cargo-contract-0.18.0/`. - // But since the `ink_linting/` folder is not part of the `cargo-contract` - // project it would not be found in this `CARGO_MANIFEST_DIR`. - if !ink_dylint_driver_dir.exists() { - println!( - "Folder `ink_linting` not found at {:?}", - ink_dylint_driver_dir - ); - ink_dylint_driver_dir = manifest_dir.join("../../../ink_linting/"); - println!( - "Added a relative path to reference the `ink_linting` folder at: {:?}", - ink_dylint_driver_dir - ); - } - let mut cmd = Command::new("cargo"); let manifest_arg = format!( @@ -178,7 +193,7 @@ fn build_and_zip_dylint_driver( println!("Invoking cargo: {:?}", cmd); let child = cmd - // capture the stdout to return from this function as bytes + // Capture the stdout to return from this function as bytes .stdout(std::process::Stdio::piped()) .spawn()?; let output = child.wait_with_output()?; diff --git a/ink_linting/Cargo.toml b/ink_linting/_Cargo.toml similarity index 100% rename from ink_linting/Cargo.toml rename to ink_linting/_Cargo.toml