Skip to content

Latest commit

 

History

83 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Git Docker Registry Cleanup

CI License: MIT TypeScript

A GitHub/Gitea action that deletes untagged/tagged images from container registries. Supports multiple registries including GHCR, Gitea, Docker Hub, and any OCI-compliant registry via Docker CLI.

⚠️ Important: Always Use Dry-Run First

This action permanently deletes tags and images from your registry. Deletions cannot be undone.

Before running in production:

  1. Always test with dry-run: true first to preview what will be deleted
  2. Review the output carefully to ensure only intended images/tags are marked for deletion
  3. Use exclude-tags to protect important tags (e.g., latest, dev, main)
  4. Start with a small scope (single package) before cleaning up multiple packages
  5. Verify your filters and patterns work as expected in dry-run mode

Example workflow:

# Step 1: Test with dry-run
- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: ghcr
    package: my-package
    dry-run: true  # ← Always start here!

# Step 2: After reviewing dry-run output, remove dry-run for actual deletion
- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: ghcr
    package: my-package
    exclude-tags: latest,dev  # Protect important tags
    # dry-run: false (default)

Features

  • Multi-Registry Support: Works with GHCR, Gitea, Docker Hub, and any OCI-compliant registry
  • Auto-Detection: Automatically detects registry type based on URL
  • Multi-Architecture Support: Handles multi-architecture images correctly
  • Referrers/Attestation Support: Supports OCI referrers and attestations (where supported)
  • Flexible Filtering: Filter by tags, age, keep N latest, exclude patterns
  • Dry-Run Mode: Test cleanup without deleting
  • Retry & Throttle: Built-in retry logic and rate limiting
  • Comprehensive Logging: Verbose debug logging support

Usage

Basic Example - GHCR

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: ghcr
    package: my-package
    dry-run: true

Gitea (Self-Hosted)

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: gitea
    registry-url: https://gitea.example.com
    token: ${{ secrets.GITEA_TOKEN }}
    package: my-package
    dry-run: true

Docker Hub

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: docker-hub
    registry-username: ${{ secrets.DOCKER_USERNAME }}
    registry-password: ${{ secrets.DOCKER_PASSWORD }}
    package: my-org/my-package
    dry-run: true

Generic OCI Registry (Harbor, Quay.io, ACR, etc.)

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: oci
    registry-url: registry.example.com
    token: ${{ secrets.REGISTRY_TOKEN }}
    package: my-org/my-package
    dry-run: true

Auto-Detection

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: auto
    registry-url: ghcr.io
    package: my-package
    dry-run: true

Keep N Latest Tagged Images

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: ghcr
    package: my-package
    dry-run: true  # Test first!
    keep-n-tagged: 10
    exclude-tags: dev,latest

Delete Untagged Images

- uses: LiquidLogicLabs/git-action-docker-cleanup@v2
  with:
    registry-type: ghcr
    package: my-package
    dry-run: true  # Test first!
    delete-untagged: true
    keep-n-untagged: 5

Inputs

Registry Configuration

Input Description Required Default
registry-type Registry type: ghcr, gitea, docker-hub, docker, or auto Yes -
registry-url Registry base URL (required for gitea, docker, and auto) No -
registry-username Registry username (for Docker Hub and docker CLI) No -
registry-password Registry password (for Docker Hub and docker CLI) No -
token Authentication token No ${{ github.token }}

Package Configuration

Input Description Required Default
owner Repository owner No Current repo owner
repository Repository name No Current repo name
package Package name to clean No -
packages Comma-separated list of packages No -
expand-packages Enable wildcard/regex support No false
use-regex Use regex for package matching No false

Cleanup Options

Input Description Required Default
dry-run Simulate cleanup without deleting No false
keep-n-tagged Keep N latest tagged images No -
keep-n-untagged Keep N latest untagged images No -
delete-untagged Delete all untagged images No false
delete-tags Delete specific tags (wildcard/regex) No -
exclude-tags Exclude tags from deletion No -
older-than Delete images older than (e.g., "30d", "2w", "1m") No -
delete-ghost-images Delete ghost images No false
delete-partial-images Delete partial multi-arch images No false
delete-orphaned-images Delete orphaned images No false
validate Validate multi-arch images after cleanup No false

API Configuration

Input Description Required Default
retry Retry count for API calls No 3
throttle Throttle delay between calls (ms) No 1000
skip-certificate-check Skip TLS certificate verification for registry API calls No false
verbose Enable verbose debug logging No false

Outputs

Output Description
deleted-count Number of images/packages deleted
kept-count Number of images/packages kept
deleted-tags List of deleted tags (comma-separated)
kept-tags List of kept tags (comma-separated)

Permissions

The action calls the registry API to delete images/tags. The job must use a token with delete scope for the target registry (e.g. GITHUB_TOKEN with packages: write for GHCR, or a PAT with equivalent permissions for other registries).

Registry Types

GHCR (GitHub Container Registry)

  • Type: ghcr
  • URL: Automatically uses ghcr.io
  • Authentication: GitHub token (defaults to GITHUB_TOKEN)
  • Features: Full support (multi-arch, referrers, attestation, cosign)

Gitea

  • Type: gitea
  • URL: Required (self-hosted instances)
  • Authentication: Gitea token
  • Features: Full support (multi-arch, referrers, attestation, cosign)
  • Note: For self-hosted Gitea, explicitly use gitea type (not auto)

Docker Hub

  • Type: docker-hub
  • URL: Automatically uses docker.io
  • Authentication: Username/password or token
  • Features: Multi-arch support, limited referrers/attestation

Generic OCI Registry (Harbor, Quay.io, ACR, Artifactory, etc.)

  • Type: oci
  • URL: Required (any OCI-compliant registry)
  • Authentication: Bearer token or username/password (Basic auth)
  • Features: Full OCI V2 API support (multi-arch, referrers, attestation, cosign)
  • Limitations:
    • Cannot list all packages (must provide package names explicitly)
    • Cannot delete individual tags (deletes entire manifest, which deletes all tags pointing to it)
    • Limited metadata (must fetch manifests to get creation dates)
  • Supported Registries: Harbor, Quay.io, Azure Container Registry, Artifactory, and any OCI-compliant registry

Docker CLI (Local Operations)

  • Type: docker
  • URL: Required (any OCI-compliant registry)
  • Authentication: Username/password or token
  • Features: Multi-arch support (via Docker CLI)
  • Requirements: Docker must be installed in runner
  • Note: Primarily for local image management, not remote registry operations

Auto-Detection

  • Type: auto
  • URL: Required
  • Behavior: Matches URL against known provider URLs, falls back to Generic OCI provider if no match
  • Known URLs:
    • ghcr.io → GHCR provider
    • docker.io, registry-1.docker.io, hub.docker.com → Docker Hub provider
    • Other URLs → Generic OCI provider (fallback)

Feature Compatibility Matrix

Feature GHCR Gitea Docker Hub Generic OCI Docker CLI
Multi-Arch
Referrers ⚠️
Attestation ⚠️
Cosign ⚠️
List Packages ✅ (local)
Delete Individual Tags ⚠️ ✅ (local)

Legend:

  • ✅ Full support
  • ⚠️ Limited support (may have restrictions)
  • ❌ Not supported

Notes:

  • GHCR: Cannot delete individual tags when multiple tags point to the same version (GitHub Package API limitation)
  • Docker Hub: Limited referrers/attestation support
  • Generic OCI: Cannot delete individual tags (deletes entire manifest), cannot list all packages
  • Docker CLI: Only works with local images, not remote registries

Security Considerations

  • ⚠️ Always Use Dry-Run First: This action permanently deletes tags and images. Always test with dry-run: true first to preview deletions before running in production.
  • Tokens: Use GitHub/Gitea secrets for authentication tokens. Never commit tokens to your repository.
  • Permissions: Ensure tokens have appropriate scopes (write:packages, delete:packages). Use the minimum required permissions.
  • Exclude Tags: Use exclude-tags to protect important images (e.g., latest, dev, main, stable).
  • Start Small: Test with a single package before cleaning up multiple packages.
  • Review Output: Carefully review dry-run output to ensure only intended images/tags are marked for deletion.

Migration from ghcr-io-cleanup-action

To migrate from ghcr-io-cleanup-action:

  1. Add registry-type: ghcr input (or use auto with registry-url: ghcr.io)
  2. All other inputs remain the same
  3. Behavior should be identical for GHCR

License

MIT

Credits

Based on the functionality of ghcr-io-cleanup-action by dataaxiom, extended to support multiple registries.

About

An action that handles cleanup of docker images and tags

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages