Skip to content

Commit

Permalink
Reuse previous version number if the build failed.
Browse files Browse the repository at this point in the history
  • Loading branch information
mjkw31 committed Nov 4, 2024
1 parent 4ab2688 commit 0f165a7
Show file tree
Hide file tree
Showing 3 changed files with 119 additions and 16 deletions.
2 changes: 0 additions & 2 deletions softpack_core/artifacts.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,7 +666,6 @@ def delete_environment(
Args:
name: the name of the environment
path: the path of the environment
commit_message: the commit message
Returns:
the OID of the new tree structure of the repository
Expand All @@ -682,7 +681,6 @@ def remove(self, full_path: Path, name: str) -> pygit2.Oid:
Args:
full_path: the parent directory to remove from
name: the file/directory to remove from the parent
commit_message: the commit message
"""
# Get repository tree
root_tree = self.repo.head.peel(pygit2.Tree)
Expand Down
55 changes: 42 additions & 13 deletions softpack_core/schemas/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,22 @@ def has_requested_recipes(self) -> bool:
"""Do any of the requested packages have an unmade recipe."""
return any(pkg.name.startswith("*") for pkg in self.packages)

@classmethod
def get_env(cls, path: Path, name: str) -> Optional["Environment"]:
"""Return an Environment object given a path.
Args:
path: A path.
Returns:
Environment: An Environment object.
"""
artifact_env = artifacts.get(path, name)
if not artifact_env:
return None

return cls.from_artifact(artifact_env)

@classmethod
def from_artifact(cls, obj: Artifacts.Object) -> Optional["Environment"]:
"""Create an Environment object from an artifact.
Expand Down Expand Up @@ -435,27 +451,40 @@ def create(cls, env: EnvironmentInput) -> CreateResponse: # type: ignore
Returns:
A message confirming the success or failure of the operation.
"""
versionless_name = env.name
version = 1

if not versionless_name:
if not env.name:
return InvalidInputError(
message="environment name must not be blank"
)

while True:
env.name = versionless_name + "-" + str(version)
response = cls.create_new_env(
env, Artifacts.built_by_softpack_file
)
if isinstance(response, CreateEnvironmentSuccess):
break

if not isinstance(response, EnvironmentAlreadyExistsError):
return response

while not isinstance(
cls.check_env_exists(
Path(env.path, env.name + "-" + str(version))
),
EnvironmentNotFoundError,
):
version += 1

if version != 1:
prevEnv = cls.get_env(
Path(env.path), env.name + "-" + str(version - 1)
)
if cast(Environment, prevEnv).state == State.failed:
version -= 1

tree_oid = artifacts.delete_environment(
env.name + "-" + str(version), env.path
)
artifacts.commit_and_push(
tree_oid, "remove failed environment"
)

env.name += "-" + str(version)
response = cls.create_new_env(env, Artifacts.built_by_softpack_file)
if not isinstance(response, CreateEnvironmentSuccess):
return response

response = cls.submit_env_to_builder(env)
if response is not None:
return response
Expand Down
78 changes: 77 additions & 1 deletion tests/integration/test_environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@
pytestmark = pytest.mark.repo


def test_create(httpx_post, testable_env_input: EnvironmentInput) -> None:
@pytest.mark.asyncio
async def test_create(
httpx_post, testable_env_input: EnvironmentInput
) -> None:
orig_input_name = testable_env_input.name
result = Environment.create(testable_env_input)
testable_env_input.name = orig_input_name
Expand Down Expand Up @@ -115,6 +118,79 @@ def test_create(httpx_post, testable_env_input: EnvironmentInput) -> None:
)
assert file_in_remote(path)

env = Environment.get_env(
testable_env_input.path, testable_env_input.name + "-2"
)
assert env.state == State.queued

upload = UploadFile(
filename=Artifacts.builder_out,
file=io.BytesIO(b""),
)

result = await Environment.write_artifact(
file=upload,
folder_path=f"{testable_env_input.path}/{testable_env_input.name}-2",
file_name=upload.filename,
)
assert isinstance(result, WriteArtifactSuccess)

env = Environment.get_env(
testable_env_input.path, testable_env_input.name + "-2"
)
assert env.state == State.failed

assert isinstance(
Environment.check_env_exists(
Path(testable_env_input.path, testable_env_input.name + "-3")
),
EnvironmentNotFoundError,
)

result = Environment.create(testable_env_input)
assert isinstance(result, CreateEnvironmentSuccess)
assert testable_env_input.name == "test_env_create-2"
testable_env_input.name = orig_input_name

assert isinstance(
Environment.check_env_exists(
Path(testable_env_input.path, testable_env_input.name + "-3")
),
EnvironmentNotFoundError,
)

env = Environment.get_env(
testable_env_input.path, testable_env_input.name + "-2"
)
assert env.state == State.queued

upload = UploadFile(
filename=Artifacts.builder_out,
file=io.BytesIO(b""),
)

result = await Environment.write_artifact(
file=upload,
folder_path=f"{testable_env_input.path}/{testable_env_input.name}-2",
file_name=upload.filename,
)
assert isinstance(result, WriteArtifactSuccess)

env = Environment.get_env(
testable_env_input.path, testable_env_input.name + "-2"
)
assert env.state == State.failed

result = Environment.create(testable_env_input)
assert isinstance(result, CreateEnvironmentSuccess)
assert testable_env_input.name == "test_env_create-2"
testable_env_input.name = orig_input_name

result = Environment.create(testable_env_input)
assert isinstance(result, CreateEnvironmentSuccess)
assert testable_env_input.name == "test_env_create-3"
testable_env_input.name = orig_input_name


def test_create_no_tags(httpx_post, testable_env_input):
testable_env_input.tags = None
Expand Down

0 comments on commit 0f165a7

Please sign in to comment.