diff --git a/.github/workflows/move/.gitignore b/.github/workflows/move/.gitignore new file mode 100644 index 0000000..243f545 --- /dev/null +++ b/.github/workflows/move/.gitignore @@ -0,0 +1,2 @@ +.aptos/ +build/ \ No newline at end of file diff --git a/.github/workflows/move/Move.toml b/.github/workflows/move/Move.toml new file mode 100644 index 0000000..10fe857 --- /dev/null +++ b/.github/workflows/move/Move.toml @@ -0,0 +1,16 @@ +[package] +name = "testing" +version = "1.0.0" +authors = [] + +[addresses] +addr = "_" + +[dev-addresses] + +[dependencies.AptosFramework] +git = "https://github.com/aptos-labs/aptos-framework.git" +rev = "mainnet" +subdir = "aptos-framework" + +[dev-dependencies] diff --git a/.github/workflows/move/sources/code.move b/.github/workflows/move/sources/code.move new file mode 100644 index 0000000..418d283 --- /dev/null +++ b/.github/workflows/move/sources/code.move @@ -0,0 +1,64 @@ +module addr::message { + use std::error; + use std::signer; + use std::string; + use aptos_framework::event; + #[test_only] + use std::debug; + + //:!:>resource + struct MessageHolder has key { + message: string::String, + } + //<:!:resource + + #[event] + struct MessageChange has drop, store { + account: address, + from_message: string::String, + to_message: string::String, + } + + /// There is no message present + const ENO_MESSAGE: u64 = 0; + + #[view] + public fun get_message(addr: address): string::String acquires MessageHolder { + assert!(exists(addr), error::not_found(ENO_MESSAGE)); + borrow_global(addr).message + } + + public entry fun set_message(account: signer, message: string::String) + acquires MessageHolder { + let account_addr = signer::address_of(&account); + if (!exists(account_addr)) { + move_to(&account, MessageHolder { + message, + }) + } else { + let old_message_holder = borrow_global_mut(account_addr); + let from_message = old_message_holder.message; + event::emit(MessageChange { + account: account_addr, + from_message, + to_message: copy message, + }); + old_message_holder.message = message; + } + } + + #[test(account = @0x1)] + public entry fun sender_can_set_message(account: signer) acquires MessageHolder { + let msg: string::String = string::utf8(b"Running test for sender_can_set_message..."); + debug::print(&msg); + + let addr = signer::address_of(&account); + aptos_framework::account::create_account_for_test(addr); + set_message(account, string::utf8(b"Hello, Blockchain")); + + assert!( + get_message(addr) == string::utf8(b"Hello, Blockchain"), + ENO_MESSAGE + ); + } +} diff --git a/.github/workflows/test-actions.yaml b/.github/workflows/test-actions.yaml index 428baa6..a0e5bd6 100644 --- a/.github/workflows/test-actions.yaml +++ b/.github/workflows/test-actions.yaml @@ -75,3 +75,14 @@ jobs: - run: curl --fail http://127.0.0.1:8081 - run: | curl --fail http://127.0.0.1:8090/v1/graphql --data-raw '{"query":"{processor_status {last_success_version processor}}"}' || if [ $? -eq 7 ]; then exit 0; else exit 1; fi + + # This also transitively tests the install-aptos-cli action. + run-test-move: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: ./test-move + with: + WORKING_DIRECTORY: .github/workflows/move + ADDITIONAL_COMPILE_ARGS: "--named-addresses addr=0x5" + ADDITIONAL_TEST_ARGS: "--named-addresses addr=0x5" diff --git a/install-aptos-cli/README.md b/install-aptos-cli/README.md new file mode 100644 index 0000000..b229c6b --- /dev/null +++ b/install-aptos-cli/README.md @@ -0,0 +1,18 @@ +## Description + +Install the Aptos CLI. By default we use the latest released version of the Aptos CLI but you can specify the version. For now this only works on Linux runners. + +## Inputs + +| parameter | description | required | default | +| --- | --- | --- | --- | +| INSTALL_DIRECTORY | The directory to install the Aptos CLI. If not specified, it will be installed in /usr/local/bin | `false` | /usr/local/bin | +| CLI_VERSION | The version of the Aptos CLI to install. If not specified, the latest version will be installed. | `false` | | +| SHELL | The shell to use for the steps. | `false` | bash | + + +## Runs + +This action is a `composite` action. + + diff --git a/install-aptos-cli/action.yaml b/install-aptos-cli/action.yaml new file mode 100644 index 0000000..7bd0c45 --- /dev/null +++ b/install-aptos-cli/action.yaml @@ -0,0 +1,31 @@ +name: Install Aptos CLI +description: Install the Aptos CLI. By default we use the latest released version of the Aptos CLI but you can specify the version. For now this only works on Linux runners. + +inputs: + INSTALL_DIRECTORY: + description: "The directory to install the Aptos CLI. If not specified, it will be installed in /usr/local/bin" + required: false + default: "/usr/local/bin" + CLI_VERSION: + description: "The version of the Aptos CLI to install. If not specified, the latest version will be installed." + required: false + SHELL: + description: "The shell to use for the steps." + required: false + default: "bash" + +runs: + using: composite + steps: + - name: Fetch installation script + shell: ${{ inputs.SHELL }} + run: curl -fSL "https://aptos.dev/scripts/install_cli.py" -o ${{ runner.temp }}/install_cli.py + + - name: Install Aptos CLI + shell: ${{ inputs.SHELL }} + run: | + if [ -n "${{ inputs.CLI_VERSION }}" ]; then + python3 ${{ runner.temp }}/install_cli.py -f -y --bin-dir ${{ inputs.INSTALL_DIRECTORY }} --cli-version ${{ inputs.CLI_VERSION }} + else + python3 ${{ runner.temp }}/install_cli.py -f -y --bin-dir ${{ inputs.INSTALL_DIRECTORY }} + fi diff --git a/install_cli.py b/install_cli.py new file mode 100644 index 0000000..0cf00b5 --- /dev/null +++ b/install_cli.py @@ -0,0 +1,571 @@ +#!/usr/bin/env python3 +r""" +This script installs the Aptos CLI. + +It will perform the following steps: +- Determine what platform (OS + arch) the script is being invoked from. +- Download the CLI. +- Put it in an appropriate location. + +This was adapted from the install script for Poetry. +""" + +import argparse +import json +import os +import platform +import shutil +import subprocess +import sys +import sysconfig +import tempfile +import warnings +from contextlib import closing +from io import UnsupportedOperation +from pathlib import Path +from typing import Optional +from urllib.request import Request, urlopen, urlretrieve + +try: + from packaging.version import Version +except ImportError: + try: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + from distutils.version import StrictVersion as Version + except ImportError: + print( + "Couldn't find distutils or packaging. We cannot check the current version of the CLI. We will install the latest version.", + ) + Version = None + +SHELL = os.getenv("SHELL", "") +WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") +MINGW = sysconfig.get_platform().startswith("mingw") +MACOS = sys.platform == "darwin" +SCRIPT = "aptos.exe" if WINDOWS else "aptos" +TEST_COMMAND = f"{SCRIPT} info" + +X86_64 = ["x86_64", "amd64"] +SUPPORTED_ARCHITECTURES = { + "macos": X86_64 + ["arm", "arm64", "aarch64"], + "linux": X86_64, + "windows": X86_64, +} + +FOREGROUND_COLORS = { + "black": 30, + "red": 31, + "green": 32, + "yellow": 33, + "blue": 34, + "magenta": 35, + "cyan": 36, + "white": 37, +} + +BACKGROUND_COLORS = { + "black": 40, + "red": 41, + "green": 42, + "yellow": 43, + "blue": 44, + "magenta": 45, + "cyan": 46, + "white": 47, +} + +OPTIONS = {"bold": 1, "underscore": 4, "blink": 5, "reverse": 7, "conceal": 8} + + +def style(fg, bg, options): + codes = [] + + if fg: + codes.append(FOREGROUND_COLORS[fg]) + + if bg: + codes.append(BACKGROUND_COLORS[bg]) + + if options: + if not isinstance(options, (list, tuple)): + options = [options] + + for option in options: + codes.append(OPTIONS[option]) + + return "\033[{}m".format(";".join(map(str, codes))) + + +STYLES = { + "info": style("cyan", None, None), + "comment": style("yellow", None, None), + "success": style("green", None, None), + "error": style("red", None, None), + "warning": style("yellow", None, None), + "b": style(None, None, ("bold",)), +} + + +def is_decorated(): + if WINDOWS: + return ( + os.getenv("ANSICON") is not None + or "ON" == os.getenv("ConEmuANSI") + or "xterm" == os.getenv("Term") + ) + + if not hasattr(sys.stdout, "fileno"): + return False + + try: + return os.isatty(sys.stdout.fileno()) + except UnsupportedOperation: + return False + + +def is_interactive(): + if not hasattr(sys.stdin, "fileno"): + return False + + try: + return os.isatty(sys.stdin.fileno()) + except UnsupportedOperation: + return False + + +def colorize(style, text): + if not is_decorated(): + return text + + return f"{STYLES[style]}{text}\033[0m" + + +def string_to_bool(value): + value = value.lower() + + return value in {"true", "1", "y", "yes"} + + +def bin_dir() -> Path: + if WINDOWS and not MINGW: + # ~ is %USERPROFILE% on Windows + return Path("~/.aptoscli/bin").expanduser() + else: + return Path("~/.local/bin").expanduser() + + +PRE_MESSAGE = """Welcome to the {aptos} CLI installer! + +This will download and install the latest version of the {aptos} CLI at this location: + +{aptos_home_bin} +""" + +POST_MESSAGE = """The {aptos} CLI ({version}) is installed now. Great! + +You can test that everything is set up by executing this command: + +{test_command} +""" + +POST_MESSAGE_NOT_IN_PATH = """The {aptos} CLI ({version}) is installed now. Great! + +To get started you need the {aptos} CLI's bin directory ({aptos_home_bin}) in your `PATH` +environment variable. +{configure_message} +Alternatively, you can call the {aptos} CLI explicitly with `{aptos_executable}`. + +You can test that everything is set up by executing: + +{test_command} +""" + +POST_MESSAGE_CONFIGURE_UNIX = """ +Add the following to your shell configuration file (e.g. .bashrc): + +export PATH="{aptos_home_bin}:$PATH" + +After this, restart your terminal. +""" + +POST_MESSAGE_CONFIGURE_FISH = """ +You can execute `set -U fish_user_paths {aptos_home_bin} $fish_user_paths` +""" + +POST_MESSAGE_CONFIGURE_WINDOWS = """ +Execute the following command to update your PATH: + +setx PATH "%PATH%;{aptos_home_bin}" + +After this, restart your terminal. +""" + + +class InstallationError(RuntimeError): + def __init__(self, return_code: int = 0, log: Optional[str] = None): + super().__init__() + self.return_code = return_code + self.log = log + + +class Installer: + # The API returns the newest items first. Accordingly we expect the CLI release to + # be in the last 100 releases (the max for a single page). + METADATA_URL = ( + "https://api.github.com/repos/aptos-labs/aptos-core/releases?per_page=100" + ) + + def __init__( + self, + version: Optional[str] = None, + force: bool = False, + accept_all: bool = False, + bin_dir: Optional[str] = None, + ) -> None: + self._version = version + self._force = force + self._accept_all = accept_all + self._bin_dir = Path(bin_dir).expanduser() if bin_dir else None + + self._release_info = None + self._latest_release_info = None + + @property + def bin_dir(self) -> Path: + if not self._bin_dir: + self._bin_dir = bin_dir() + return self._bin_dir + + @property + def bin_path(self): + return self.bin_dir.joinpath(SCRIPT) + + @property + def release_info(self): + if not self._release_info: + self._release_info = json.loads(self._get(self.METADATA_URL).decode()) + return self._release_info + + @property + def latest_release_info(self): + # Iterate through the releases and find the latest CLI release. + for release in self.release_info: + if release["tag_name"].startswith("aptos-cli-"): + return release + raise RuntimeError("Failed to find latest CLI release") + + def run(self) -> int: + try: + version, _current_version = self.get_version() + except ValueError: + return 1 + + if version is None: + return 0 + + try: + target = self.get_target() + except: + return 1 + + if target is None: + return 0 + + self._write(colorize("info", "Determined target to be: {}".format(target))) + self._write("") + + self.display_pre_message() + + try: + self.install(version, target) + except subprocess.CalledProcessError as e: + raise InstallationError(return_code=e.returncode, log=e.output.decode()) + + self._write("") + self.display_post_message(version) + + return 0 + + def install(self, version, target): + self._install_comment(version, "Downloading...") + + self.bin_dir.mkdir(parents=True, exist_ok=True) + if self.bin_path.exists(): + self.bin_path.unlink() + + url = self.build_binary_url(version, target) + + with tempfile.TemporaryDirectory() as tmpdirname: + zip_file = os.path.join(tmpdirname, "aptos-cli.zip") + urlretrieve(url, zip_file) + # This assumes that the binary within the zip file is always + # called `aptos` / `aptos.exe`. + shutil.unpack_archive(zip_file, self.bin_dir) + + os.chmod(self.bin_path, 0o755) + + self._install_comment(version, "Done!") + return 0 + + def _install_comment(self, version: str, message: str): + self._write( + "Installing {} CLI ({}): {}".format( + colorize("info", "Aptos"), + colorize("b", version), + colorize("comment", message), + ) + ) + + def build_binary_url(self, version: str, target: str) -> str: + return f"https://github.com/aptos-labs/aptos-core/releases/download/aptos-cli-v{version}/aptos-cli-{version}-{target}.zip" + + def display_pre_message(self) -> None: + kwargs = { + "aptos": colorize("info", "Aptos"), + "aptos_home_bin": colorize("comment", self.bin_dir), + } + self._write(PRE_MESSAGE.format(**kwargs)) + + def display_post_message(self, version: str) -> None: + if WINDOWS: + return self.display_post_message_windows(version) + + if SHELL == "fish": + return self.display_post_message_fish(version) + + return self.display_post_message_unix(version) + + def get_windows_path_var(self) -> Optional[str]: + import winreg + + with winreg.ConnectRegistry(None, winreg.HKEY_CURRENT_USER) as root: + with winreg.OpenKey(root, "Environment", 0, winreg.KEY_ALL_ACCESS) as key: + path, _ = winreg.QueryValueEx(key, "PATH") + + return path + + def display_post_message_windows(self, version: str) -> None: + path = self.get_windows_path_var() + + message = POST_MESSAGE_NOT_IN_PATH + if path and str(self.bin_dir) in path: + message = POST_MESSAGE + + self._write( + message.format( + aptos=colorize("info", "Aptos"), + version=colorize("b", version), + aptos_home_bin=colorize("comment", self.bin_dir), + aptos_executable=colorize("b", self.bin_path), + configure_message=POST_MESSAGE_CONFIGURE_WINDOWS.format( + aptos_home_bin=colorize("comment", self.bin_dir) + ), + test_command=colorize("b", TEST_COMMAND), + ) + ) + + def display_post_message_fish(self, version: str) -> None: + fish_user_paths = subprocess.check_output( + ["fish", "-c", "echo $fish_user_paths"] + ).decode("utf-8") + + message = POST_MESSAGE_NOT_IN_PATH + if fish_user_paths and str(self.bin_dir) in fish_user_paths: + message = POST_MESSAGE + + self._write( + message.format( + aptos=colorize("info", "Aptos"), + version=colorize("b", version), + aptos_home_bin=colorize("comment", self.bin_dir), + aptos_executable=colorize("b", self.bin_path), + configure_message=POST_MESSAGE_CONFIGURE_FISH.format( + aptos_home_bin=colorize("comment", self.bin_dir) + ), + test_command=colorize("b", TEST_COMMAND), + ) + ) + + def display_post_message_unix(self, version: str) -> None: + paths = os.getenv("PATH", "").split(":") + + message = POST_MESSAGE_NOT_IN_PATH + if paths and str(self.bin_dir) in paths: + message = POST_MESSAGE + + self._write( + message.format( + aptos=colorize("info", "Aptos"), + version=colorize("b", version), + aptos_home_bin=colorize("comment", self.bin_dir), + aptos_executable=colorize("b", self.bin_path), + configure_message=POST_MESSAGE_CONFIGURE_UNIX.format( + aptos_home_bin=colorize("comment", self.bin_dir) + ), + test_command=colorize("b", TEST_COMMAND), + ) + ) + + def get_version(self): + latest_version = self.latest_release_info["tag_name"].split("-v")[-1] + self._write(colorize("info", "Latest CLI release: {}".format(latest_version))) + + if self._force: + return latest_version, None + + binary_path = self.bin_path + try: + out = subprocess.check_output( + [binary_path, "--version"], + universal_newlines=True, + ) + current_version = current_version = out.split(" ")[-1].rstrip().lstrip() + except Exception: + current_version = None + + self._write( + colorize("info", "Currently installed CLI: {}".format(current_version)) + ) + + with warnings.catch_warnings(): + warnings.simplefilter("ignore", category=DeprecationWarning) + if ( + Version is not None + and current_version + and Version(current_version) >= Version(latest_version) + ): + self._write("") + self._write( + f'The latest version ({colorize("b", latest_version)}) is already installed.' + ) + + return None, current_version + else: + self._write(f"Installing {colorize('b', latest_version)}") + + return latest_version, current_version + + # Given the OS and CPU architecture, determine the "target" to download. + def get_target(self): + # We only look this up for validation, we only need the OS to figure out which + # binary to download right now since we only build for x86_64 right now. + arch = (platform.machine() or platform.processor()).lower() + + os = "windows" if WINDOWS else "macos" if MACOS else "linux" + if not arch in SUPPORTED_ARCHITECTURES[os]: + self._write( + colorize( + "error", + f"The given OS ({os}) + CPU architecture ({arch}) is not supported.", + ) + ) + return None + + if WINDOWS: + return "Windows-x86_64" + + if MACOS: + sys.stdout.write( + colorize( + "error", + "You are trying to install from macOS. Please use brew to install Aptos CLI instead - [brew install aptos]", + ) + ) + self._write("") + sys.exit(1) + + # On Linux, we check what version of OpenSSL we're working with to figure out + # which binary to download. + try: + out = subprocess.check_output( + ["openssl", "version"], + universal_newlines=True, + ) + openssl_version = out.split(" ")[1].rstrip().lstrip() + except Exception: + self._write( + colorize( + "warning", + "Could not determine OpenSSL version, assuming older version (1.x.x)", + ) + ) + openssl_version = "1.0.0" + + if openssl_version.startswith("3."): + return "Ubuntu-22.04-x86_64" + + return "Ubuntu-x86_64" + + def _write(self, line) -> None: + sys.stdout.write(line + "\n") + + def _get(self, url): + request = Request(url, headers={"User-Agent": "Aptos CLI Installer"}) + + with closing(urlopen(request)) as r: + return r.read() + + +def main(): + if sys.version_info.major < 3 or sys.version_info.minor < 6: + sys.stdout.write( + colorize("error", "This installer requires Python 3.6 or newer to run!") + ) + # Return error code. + return 1 + + parser = argparse.ArgumentParser( + description="Installs the latest version of the Aptos CLI" + ) + parser.add_argument( + "-f", + "--force", + help="Forcibly install on top of existing version", + action="store_true", + default=False, + ) + parser.add_argument( + "-y", + "--yes", + help="Accept all prompts", + dest="accept_all", + action="store_true", + default=False, + ) + parser.add_argument( + "--bin-dir", + help="If given, the CLI binary will be downloaded here instead", + ) + + args = parser.parse_args() + + installer = Installer( + force=args.force, + accept_all=args.accept_all or not is_interactive(), + bin_dir=args.bin_dir, + ) + + try: + return installer.run() + except InstallationError as e: + installer._write(colorize("error", "Aptos CLI installation failed.")) + + if e.log is not None: + import traceback + + _, path = tempfile.mkstemp( + suffix=".log", + prefix="aptos-cli-installer-error-", + dir=str(Path.cwd()), + text=True, + ) + installer._write(colorize("error", f"See {path} for error logs.")) + text = f"{e.log}\nTraceback:\n\n{''.join(traceback.format_tb(e.__traceback__))}" + Path(path).write_text(text) + + return e.return_code + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/test-move/README.md b/test-move/README.md new file mode 100644 index 0000000..762a486 --- /dev/null +++ b/test-move/README.md @@ -0,0 +1,27 @@ +## Description + +Run move formatting checks, linting, compilation, and tests. You must checkout the code prior to using this. This uses the latest released version of the Aptos CLI. + +## Inputs + +| parameter | description | required | default | +| --- | --- | --- | --- | +| WORKING_DIRECTORY | The directory to run the commands from. | `false` | . | +| SKIP_FMT | If true, skip formatting. | `false` | false | +| SKIP_LINT | If true, skip linting. | `false` | false | +| SKIP_COMPILE | If true, skip compilation. | `false` | false | +| SKIP_TEST | If true, skip tests. | `false` | false | +| ADDITIONAL_FMT_ARGS | Additional arguments to pass to the CLI when running movefmt. | `false` | | +| ADDITIONAL_LINT_ARGS | Additional arguments to pass to the CLI when running move lint. | `false` | | +| ADDITIONAL_COMPILE_ARGS | Additional arguments to pass to the CLI when running move compile. | `false` | | +| ADDITIONAL_TEST_ARGS | Additional arguments to pass to the CLI when running move test. | `false` | | +| CLI_VERSION | The version of the Aptos CLI to install. If not specified, the latest version will be installed. | `false` | | +| SKIP_INSTALLING_CLI | If true, skip installing the Aptos CLI. We will assume it is already on the PATH. | `false` | false | +| SHELL | The shell to use for the steps. | `false` | bash | + + +## Runs + +This action is a `composite` action. + + diff --git a/test-move/action.yaml b/test-move/action.yaml new file mode 100644 index 0000000..1526710 --- /dev/null +++ b/test-move/action.yaml @@ -0,0 +1,95 @@ +name: Move Tests +description: Run move formatting checks, linting, compilation, and tests. You must checkout the code prior to using this. This uses the latest released version of the Aptos CLI. + +inputs: + WORKING_DIRECTORY: + description: "The directory to run the commands from." + required: false + default: "." + SKIP_FMT: + description: "If true, skip formatting." + required: false + default: "false" + SKIP_LINT: + description: "If true, skip linting." + required: false + default: "false" + SKIP_COMPILE: + description: "If true, skip compilation." + required: false + default: "false" + SKIP_TEST: + description: "If true, skip tests." + required: false + default: "false" + ADDITIONAL_FMT_ARGS: + description: "Additional arguments to pass to the CLI when running movefmt." + required: false + ADDITIONAL_LINT_ARGS: + description: "Additional arguments to pass to the CLI when running move lint." + required: false + ADDITIONAL_COMPILE_ARGS: + description: "Additional arguments to pass to the CLI when running move compile." + required: false + ADDITIONAL_TEST_ARGS: + description: "Additional arguments to pass to the CLI when running move test." + required: false + CLI_VERSION: + description: "The version of the Aptos CLI to install. If not specified, the latest version will be installed." + required: false + SKIP_INSTALLING_CLI: + description: "If true, skip installing the Aptos CLI. We will assume it is already on the PATH." + required: false + default: "false" + SHELL: + description: "The shell to use for the steps." + required: false + default: "bash" + +runs: + using: composite + steps: + - name: Install Aptos CLI + uses: ./install-aptos-cli + if: ${{ inputs.SKIP_INSTALLING_CLI == 'false' }} + with: + CLI_VERSION: ${{ inputs.CLI_VERSION }} + + - name: Install movefmt + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + run: aptos update movefmt + + - name: Check for formatting changes + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + if: ${{ inputs.SKIP_FMT == 'false' }} + run: aptos move fmt ${{ inputs.ADDITIONAL_FMT_ARGS }} + - name: Return error if formatting changes detected + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + if: ${{ inputs.SKIP_FMT == 'false' }} + run: | + if git diff --name-only | grep "sources/" > /dev/null; then + echo "Error: Found unstaged changes in sources/ directory after formatting" + git diff + exit 1 + fi + + - name: Lint code + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + if: ${{ inputs.SKIP_LINT == 'false' }} + run: aptos move lint ${{ inputs.ADDITIONAL_LINT_ARGS }} + + - name: Compile code + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + if: ${{ inputs.SKIP_COMPILE == 'false' }} + run: aptos move compile ${{ inputs.ADDITIONAL_COMPILE_ARGS }} + + - name: Run move tests + shell: ${{ inputs.SHELL }} + working-directory: ${{ inputs.WORKING_DIRECTORY }} + if: ${{ inputs.SKIP_TEST == 'false' }} + run: aptos move test ${{ inputs.ADDITIONAL_TEST_ARGS }}