Skip to content

Commit

Permalink
Adding github actions to test and format
Browse files Browse the repository at this point in the history
  • Loading branch information
zachgiordano committed Aug 2, 2023
1 parent 07964ff commit 05fddd8
Show file tree
Hide file tree
Showing 17 changed files with 277 additions and 83 deletions.
40 changes: 40 additions & 0 deletions .github/actions/init-environment/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: "Init Environment"
runs:
using: "composite"
steps:
- name: Checkout actions
uses: actions/checkout@v3

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}

- name: Install and configure Poetry
uses: snok/install-poetry@v1
with:
virtualenvs-create: true
virtualenvs-in-project: true
installer-parallel: true

- name: Load cached venv
id: cached-poetry-dependencies
uses: actions/cache@v3
with:
path: .venv
key: venv-${{ runner.os }}-${{ steps.setup-python.outputs.python-version }}-${{ hashFiles('**/poetry.lock') }}

- name: Install dependencies
if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true'
run: poetry install --no-interaction --no-root
shell: bash

- name: Install project
run: poetry install --no-interaction
shell: bash

- name: Activate venv
run: |
source .venv/bin/activate
echo PATH=$PATH >> $GITHUB_ENV
shell: bash
19 changes: 19 additions & 0 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Format CI

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout actions
uses: actions/checkout@v3
- name: Run black
uses: psf/black@stable
with:
options: "--check --diff --color"
src: "."
22 changes: 22 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Tests

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11"]
steps:
- name: Checkout actions
uses: actions/checkout@v3
- name: Init environment
uses: ./.github/actions/init-environment
- name: Run tests
run: pytest
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ log.log
**/node_modules
*.pyc
*.vsix
.vscode
**/.vscode/.ropeproject/**
**/testFiles/**/.cache/**
*.noseids
Expand Down
45 changes: 23 additions & 22 deletions griptape/cli/commands/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from griptape.cli.core.utils.constants import DEFAULT_ENDPOINT_URL


@click.group()
@click.pass_context
def app(ctx):
Expand All @@ -21,18 +22,20 @@ def app(ctx):
required=True,
)
@click.option(
"--package_manager", "-p",
"--package_manager",
"-p",
type=click.Choice(["pip", "poetry"]),
help="Package manager to use for Griptape app.",
default="pip",
show_default=True
show_default=True,
)
@click.option(
"--directory", "-d",
"--directory",
"-d",
type=str,
help="Directory to create a new app in.",
default=".",
show_default=True
show_default=True,
)
def new(name: str, package_manager: str, directory: str) -> None:
"""
Expand All @@ -41,25 +44,18 @@ def new(name: str, package_manager: str, directory: str) -> None:

echo(f"Initializing app {name}")

App(
name=name,
package_manager=package_manager
).generate(directory)
App(name=name, package_manager=package_manager).generate(directory)


@app.command(name="run")
@click.option("--arg", "-a", multiple=True, type=str, required=True)
@click.option(
"--arg", "-a",
multiple=True,
type=str,
required=True
)
@click.option(
"--directory", "-d",
"--directory",
"-d",
type=str,
help="Directory where app resides. Defaults to current directory.",
default=os.getcwd(),
show_default=True
show_default=True,
)
def run(arg: list[str], directory: str) -> TextArtifact:
"""
Expand All @@ -72,30 +68,35 @@ def run(arg: list[str], directory: str) -> TextArtifact:

@app.command(name="deploy")
@click.option(
"--directory", "-d",
"--directory",
"-d",
type=str,
help="Directory where app resides. Defaults to current directory.",
default=os.getcwd(),
show_default=True
show_default=True,
)
@click.option(
"--endpoint-url", "-e",
"--endpoint-url",
"-e",
type=str,
required=False,
help="Override default endpoint url",
default=DEFAULT_ENDPOINT_URL,
)
@click.option(
"--name", "-n",
"--name",
"-n",
type=str,
help="Griptape Cloud app name",
default=None,
required=False
required=False,
)
def deploy(directory: str, endpoint_url: str, name: str) -> None:
"""
Deploy a Griptape app to Griptape Cloud.
"""

app_deployer = AppDeployer(app_directory=directory, endpoint_url=endpoint_url, name=name)
app_deployer = AppDeployer(
app_directory=directory, endpoint_url=endpoint_url, name=name
)
app_deployer.deploy()
8 changes: 6 additions & 2 deletions griptape/cli/commands/cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
from click import echo
from griptape.cli.core.utils.auth import get_auth_token


@click.group()
@click.pass_context
def cloud(ctx):
pass


@cloud.command(name="login")
@click.option(
"--relogin", "-r",
"--relogin",
"-r",
is_flag=True,
help="Set flag to force relogin",
)
@click.option(
"--endpoint-url", "-e",
"--endpoint-url",
"-e",
type=str,
required=False,
help="Override default endpoint url",
Expand Down
12 changes: 9 additions & 3 deletions griptape/cli/core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,20 @@

@define
class App:
DEFAULT_TEMPLATE_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), "templates", "app")
DEFAULT_TEMPLATE_PATH = os.path.join(
os.path.dirname(os.path.abspath(__file__)), "templates", "app"
)

name: str = field(kw_only=True)
package_manager: str = field(kw_only=True)
template_path: Optional[str] = field(default=None, kw_only=True)

def generate(self, directory: str = ".") -> None:
template = self.DEFAULT_TEMPLATE_PATH if self.template_path is None else self.template_path
template = (
self.DEFAULT_TEMPLATE_PATH
if self.template_path is None
else self.template_path
)

cookiecutter(
template,
Expand All @@ -23,6 +29,6 @@ def generate(self, directory: str = ".") -> None:
extra_context={
"app_name": self.name,
"package_name": stringcase.snakecase(self.name),
"package_manager": self.package_manager
"package_manager": self.package_manager,
},
)
39 changes: 20 additions & 19 deletions griptape/cli/core/app_deployer.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

@define
class AppDeployer:

app_directory: str = field(kw_only=True)
endpoint_url: str = field(kw_only=True)
name: Optional[str] = field(kw_only=True, default=None)
Expand All @@ -21,13 +20,14 @@ def __attrs_post_init__(self):

@app_directory.validator
def validate_app_directory(self, _, app_directory: str) -> None:
if not os.path.exists(app_directory) or not os.path.exists(os.path.join(app_directory, 'app.py')):
if not os.path.exists(app_directory) or not os.path.exists(
os.path.join(app_directory, "app.py")
):
raise ValueError(f"App doesn't exist in directory: {app_directory}")

def deploy(self):

tmp_dir = zip_file = None

try:
tmp_dir = self._create_deployment_tmp_dir()
zip_file = self._create_deployment_zip_file(tmp_dir)
Expand All @@ -41,34 +41,35 @@ def deploy(self):
def _create_deployment_tmp_dir(self) -> str:
# Copy to new dir to ignore certain patterns
# TODO: Should more patterns be ignored?
return shutil.copytree(self.app_directory, os.path.join(self.app_directory, "zip_tmp"), ignore=shutil.ignore_patterns('.venv*'))

return shutil.copytree(
self.app_directory,
os.path.join(self.app_directory, "zip_tmp"),
ignore=shutil.ignore_patterns(".venv*"),
)

def _create_deployment_zip_file(self, tmp_dir: str) -> str:
zip = shutil.make_archive("artifact", "zip", tmp_dir)
shutil.move(zip, self.app_directory)
return os.path.join(self.app_directory, 'artifact.zip')
return os.path.join(self.app_directory, "artifact.zip")

def _deploy_app(self, zip_file: str) -> None:
url = urljoin(self.endpoint_url, 'apps/')
data = {
'name': self.name or os.path.basename(self.app_directory)
}
url = urljoin(self.endpoint_url, "apps/")
data = {"name": self.name or os.path.basename(self.app_directory)}
headers = {
'Authorization': f"Token {get_auth_token(relogin=False, endpoint_url=self.endpoint_url)}"
"Authorization": f"Token {get_auth_token(relogin=False, endpoint_url=self.endpoint_url)}"
}

with open(zip_file, 'rb') as file:
files = {
'zip_file': file
}
with open(zip_file, "rb") as file:
files = {"zip_file": file}
response = requests.post(url=url, data=data, files=files, headers=headers)
if response.status_code != 201:
raise Exception("Failed to create App")
echo(f"Response: {response.text}")

def _clean_up_deployment_artifacts(self, tmp_dir: Optional[str], zip_file: Optional[str]) -> None:
def _clean_up_deployment_artifacts(
self, tmp_dir: Optional[str], zip_file: Optional[str]
) -> None:
if tmp_dir and os.path.exists(tmp_dir):
shutil.rmtree(tmp_dir)
if zip_file and os.path.exists(zip_file):
os.remove(zip_file)

9 changes: 6 additions & 3 deletions griptape/cli/core/structure_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@

@define
class StructureRunner:

arg: list[str] = field(kw_only=True)
app_directory: Optional[str] = field(kw_only=True, default=Factory(lambda: os.getcwd()))
app_directory: Optional[str] = field(
kw_only=True, default=Factory(lambda: os.getcwd())
)

def __attrs_post_init__(self):
self.app_directory = os.path.abspath(self.app_directory)
Expand All @@ -30,4 +31,6 @@ def run(self):
def _install_pip_dependencies(self) -> None:
requirements_path = os.path.join(self.app_directory, "requirements.txt")
if os.path.exists(requirements_path):
subprocess.check_call([sys.executable, "-m", "pip", "install", "-r", requirements_path])
subprocess.check_call(
[sys.executable, "-m", "pip", "install", "-r", requirements_path]
)
Loading

0 comments on commit 05fddd8

Please sign in to comment.