Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,8 @@ jobs:
context: "./posit-bakery/test/resources/multiplatform/"
dev-versions: include

clean:
name: Clean
if: github.ref == 'refs/heads/main'
with-macros-clean-caches:
name: Clean Caches (with-macros suite)
permissions:
contents: read
packages: write
Expand All @@ -141,6 +140,23 @@ jobs:
context: "./posit-bakery/test/resources/with-macros/"
remove-dangling-caches: true
remove-caches-older-than: 14
clean-temporary-images: false # TODO: flip to true if this build starts using the native workflow

multiplatform-clean-caches:
name: Clean Caches (multiplatform suite)
permissions:
contents: read
packages: write
needs:
- bakery
- bakery-native

uses: "./.github/workflows/clean.yml"
with:
version: ${{ github.head_ref || github.ref_name }}
context: "./posit-bakery/test/resources/multiplatform/"
remove-dangling-caches: true
remove-caches-older-than: 14
remove-dangling-temporary-images: false
remove-temporary-images-older-than: 3

Expand Down
10 changes: 8 additions & 2 deletions posit-bakery/posit_bakery/cli/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,14 @@ def cache_registry(

log.info(f"Cleaning cache registries in {registry}")

config.clean_caches(
errors = config.clean_caches(
remove_untagged=untagged,
remove_older_than=timedelta(days=older_than) if older_than else None,
dry_run=dry_run,
)
if errors:
log.error(f"Completed with {len(errors)} errors encountered during cleanup.")
raise typer.Exit(code=1)


@app.command()
Expand Down Expand Up @@ -140,8 +143,11 @@ def temp_registry(

log.info(f"Cleaning temporary registries in {registry}")

config.clean_temporary(
errors = config.clean_temporary(
remove_untagged=untagged,
remove_older_than=timedelta(days=older_than) if older_than else None,
dry_run=dry_run,
)
if errors:
log.error(f"Completed with {len(errors)} errors encountered during cleanup.")
raise typer.Exit(code=1)
30 changes: 20 additions & 10 deletions posit-bakery/posit_bakery/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -817,14 +817,19 @@ def clean_caches(
"""
target_caches = list(set([target.cache_name.split(":")[0] for target in self.targets]))

errors = []
for target_cache in target_caches:
ghcr.clean_temporary_artifacts(
ghcr_registry=target_cache,
remove_untagged=remove_untagged,
remove_older_than=remove_older_than,
dry_run=dry_run,
errors.extend(
ghcr.clean_temporary_artifacts(
ghcr_registry=target_cache,
remove_untagged=remove_untagged,
remove_older_than=remove_older_than,
dry_run=dry_run,
)
)

return errors

def clean_temporary(
self,
remove_untagged: bool = True,
Expand All @@ -839,10 +844,15 @@ def clean_temporary(
"""
target_caches = list(set([target.temp_name for target in self.targets]))

errors = []
for target_cache in target_caches:
ghcr.clean_temporary_artifacts(
ghcr_registry=target_cache,
remove_untagged=remove_untagged,
remove_older_than=remove_older_than,
dry_run=dry_run,
errors.extend(
ghcr.clean_temporary_artifacts(
ghcr_registry=target_cache,
remove_untagged=remove_untagged,
remove_older_than=remove_older_than,
dry_run=dry_run,
)
)

return errors
10 changes: 8 additions & 2 deletions posit-bakery/posit_bakery/registry_management/ghcr/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import os
from urllib.parse import quote

from github import Auth, Github
from github import Auth, Github, GithubException

from posit_bakery.registry_management.ghcr.models import GHCRPackageVersions, GHCRPackageVersion

Expand Down Expand Up @@ -68,5 +68,11 @@ def delete_package_version(self, version: GHCRPackageVersion):
)

def delete_package_versions(self, versions: GHCRPackageVersions):
errors = []
for version in versions.versions:
self.delete_package_version(version)
try:
self.delete_package_version(version)
except GithubException as e:
logging.error(f"Failed to delete package version {version.html_url}: {e.message}")
errors.append((version.id, e.message))
return errors
24 changes: 19 additions & 5 deletions posit-bakery/posit_bakery/registry_management/ghcr/clean.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import re
from datetime import timedelta

from github import GithubException

from posit_bakery.log import stdout_console
from posit_bakery.registry_management.ghcr.api import GHCRClient
from posit_bakery.registry_management.ghcr.models import GHCRPackageVersions
Expand All @@ -15,7 +17,7 @@ def clean_temporary_artifacts(
remove_untagged: bool = True,
remove_older_than: timedelta | None = None,
dry_run: bool = False,
):
) -> list[GithubException]:
"""Cleans up temporary caches and images that are not tagged or are older than a given timedelta."""
# Check that the registry matches the expected pattern.
match = REGISTRY_PATTERN.match(ghcr_registry)
Expand All @@ -28,7 +30,11 @@ def clean_temporary_artifacts(

# Retrieve all package versions.
client = GHCRClient(organization)
package_versions = client.get_package_versions(organization, package)
try:
package_versions = client.get_package_versions(organization, package)
except GithubException as e:
log.error(f"Failed to retrieve package versions for {ghcr_registry}: {e}")
return [e]

# Filter package versions that should be deleted.
versions_to_delete = []
Expand All @@ -48,10 +54,12 @@ def clean_temporary_artifacts(
if dry_run:
stdout_console.print_json(versions_to_delete.model_dump_json(indent=2))
else:
client.delete_package_versions(versions_to_delete)
return client.delete_package_versions(versions_to_delete)
else:
log.info(f"No artifacts to remove from {ghcr_registry}")

return []


def clean_registry(
image_registry: str,
Expand All @@ -69,7 +77,11 @@ def clean_registry(

# Retrieve all package versions.
client = GHCRClient(organization)
package_versions = client.get_package_versions(organization, package)
try:
package_versions = client.get_package_versions(organization, package)
except GithubException as e:
log.error(f"Failed to retrieve package versions for {image_registry}: {e}")
return [e]

# Filter package versions that should be deleted.
versions_to_delete = []
Expand All @@ -90,6 +102,8 @@ def clean_registry(
if dry_run:
stdout_console.print_json(versions_to_delete.model_dump_json(indent=2))
else:
client.delete_package_versions(versions_to_delete)
return client.delete_package_versions(versions_to_delete)
else:
log.info(f"No versions to remove from {image_registry}")

return []