Skip to content

Conversation

balcsida
Copy link
Contributor

@balcsida balcsida commented Aug 8, 2025

Purpose of the PR

This PR introduces a new --untagged-only flag to the purge command, enabling users to clean up untagged manifests independently without affecting tagged manifests. This addresses the confusion and limitations reported in various issues and provides a comprehensive solution for dangling manifest cleanup.

Key Features Added

  1. New --untagged-only flag: Exclusively targets untagged manifests without deleting any tags first
  2. Optional --ago and --keep support: When used with --untagged-only, these flags become optional and provide additional filtering capabilities:
    • --ago: Filter untagged manifests by age (delete only manifests older than specified duration)
    • --keep: Preserve the most recent N untagged manifests
  3. Enhanced documentation: Comprehensive help text and examples clearly distinguish between --untagged and --untagged-only

Implementation Details

  • Flag validation: Improved validation logic with better UX (validation happens before authentication)
  • Mutual exclusivity: --untagged and --untagged-only are mutually exclusive to prevent confusion
  • Age filtering: Added manifest age filtering support in purgeDanglingManifests function
  • Keep logic: Added support to preserve the most recent untagged manifests when --keep is specified
  • Comprehensive testing: Added extensive unit tests and integration test scripts

Enhanced User Experience

  • Clear flag descriptions: Updated help text clearly explains when to use each flag
  • Organized examples: Help examples are categorized into:
    • TAG DELETION EXAMPLES (traditional workflow)
    • DANGLING MANIFEST CLEANUP EXAMPLES (new --untagged-only workflow)
    • ADVANCED OPTIONS
  • Better error messages: Improved validation with clearer error messaging

Usage Examples

# Basic dangling manifest cleanup
acr purge -r example --untagged-only

# Clean up dangling manifests in specific repository
acr purge -r example --filter "hello-world:.*" --untagged-only

# Clean up old dangling manifests (older than 3 days), keeping 5 most recent
acr purge -r example --untagged-only --ago 3d --keep 5

# Traditional workflow: delete tags then clean up resulting dangling manifests
acr purge -r example --filter "hello-world:\w*test\w*" --ago 5d --untagged

Key Differences Between Flags

  • --untagged: Used as a cleanup step after tag deletion. Requires --filter and --ago. Deletes tags first, then cleans up untagged manifests left behind.
  • --untagged-only: Primary tool for dangling manifest cleanup. Works independently without deleting tags. Optional --filter, --ago, and --keep for targeted cleanup.

Breaking Changes
None. The existing --untagged flag behavior remains unchanged for backward compatibility.

Testing

  • All existing tests pass
  • Added comprehensive unit tests for new functionality
  • Added integration test scripts for real Azure registry testing
  • Fixed edge cases and improved error handling

Fixes #64
Fixes #83
Fixes #95
Fixes #480
Fixes #486

@balcsida balcsida force-pushed the feat/untagged-only-flag branch from 1dda8ef to fe3c53c Compare August 13, 2025 10:48
@balcsida balcsida marked this pull request as ready for review August 13, 2025 11:02
@balcsida
Copy link
Contributor Author

@estebanreyl, as the --untagged flag caused so much confusion in the past, do you think it would make sense to deprecate it and have some new name for this flag to prevent any accidental manifest deletion?

- Add unit tests for untagged-only flag validation
- Add integration test script for real Azure registry testing
- Update main test script with untagged-only test cases
- Fix index out of range bug in GetUntaggedManifests
- Test scenarios include dry-run, locked manifests, and filters
- Remove GetManifest expectations for untagged manifests (not called)
- Fix UpdateAcrManifestAttributes mock to return proper response
- Update GetRepositories test to match actual behavior
- Update mutual exclusivity test to accept Cobra's error message
- All unit tests now passing (100% success rate)
@balcsida balcsida force-pushed the feat/untagged-only-flag branch from e718249 to a160bef Compare August 19, 2025 12:34
@estebanreyl
Copy link
Contributor

I like the change, but I am little hesitant when it comes to this type of usability change scenarios, so I messaged a couple of PMs to take a look and will see what they say and will update. I am sorry its taken so long

@balcsida
Copy link
Contributor Author

Again, no worries at all, @estebanreyl! 🙇

@FeynmanZhou
Copy link
Member

Hey @balcsida ,

Thanks for making several PRs to acr purge. I am wondering if retention policy is a good fit for your scenario? When a retention policy is enabled, untagged manifests in the registry are automatically deleted after a number of days you set.

@balcsida
Copy link
Contributor Author

@FeynmanZhou Thanks for the suggestion! I'm familiar with retention policies, but they don't address the specific issues this PR solves:

Organizational constraints

Some organizations (like ours) face significant bureaucratic hurdles when implementing policies (especially preview ones). A scheduled cleanup pipeline using existing CLI tools is often much more practical to deploy and manage.

User experience issues

The linked issues (#64, #83, #95, #480, #486) demonstrate a clear pattern: users consistently expect the --untagged flag to behave like the proposed --untagged-only flag. The fact that multiple users took the effort to find this repository and report these issues suggests this confusion is causing real problems in production environments.

Complementary solution

Rather than replacing retention policies, this PR provides an alternative approach for teams that need more granular control or face organizational constraints. The --untagged-only flag offers:

  • Immediate deployment without policy approval processes
  • Scriptable control with --ago and --keep options
  • Clear semantics that align with user expectations

This change maintains full backward compatibility while preventing the unintended manifest deletions that several users have reported.

@balcsida balcsida changed the title feat: add --untagged-only flag for independent untagged manifest cleanup feat: add --untagged-only for independent manifest cleanup Oct 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

3 participants