Documents
deleting-packages
deleting-packages
Type
External
Status
Published
Created
Mar 5, 2026
Updated
Mar 5, 2026
Source
View

Tutorial Overview#

You will learn how to:

  1. Delete Draft and Proposed PackageRevisions directly
  2. Propose Published PackageRevisions for deletion
  3. Approve or reject deletion proposals
  4. Understand the deletion workflow and safety mechanisms

{{% alert title="Note" color="primary" %}}
This tutorial assumes a porch repository is initialized with the "porch-test" name.
Replace any "porch-test" value with your repository's name in the commands below.
{{% /alert %}}


Understanding PackageRevision Deletion#

PackageRevision deletion in Porch follows different workflows depending on the lifecycle state:

Direct Deletion:

  • Draft and Proposed PackageRevisions can be deleted immediately
  • No approval process required
  • Permanently removes the PackageRevision and its Git branch

Deletion Proposal Workflow:

  • Published PackageRevisions require a two-step deletion process
  • First propose deletion, then approve the proposal
  • Provides safety mechanism to prevent accidental deletion of production packages

Branch-Tracking PackageRevisions:

  • When you publish a PackageRevision, Porch automatically creates a "main" branch-tracking PackageRevision
  • These have revision -1 and workspace name main
  • They track the current state of the package on the main Git branch
  • Important: These are managed automatically by Porch and should not be directly modified
  • The only user interaction should be deletion after all regular PackageRevisions of that specific package are deleted

Step 1: Create Test PackageRevisions#

Let's create some test PackageRevisions to demonstrate the deletion workflows:

# Create a Draft PackageRevision
porchctl rpkg init test-draft-package \
  --namespace=default \
  --repository=porch-test \
  --workspace=draft-v1 \
  --description="Test package for deletion"

# Create a Proposed PackageRevision
porchctl rpkg init test-proposed-package \
  --namespace=default \
  --repository=porch-test \
  --workspace=proposed-v1 \
  --description="Test package for deletion"

porchctl rpkg propose porch-test.test-proposed-package.proposed-v1 --namespace=default

# Create a Published PackageRevision
porchctl rpkg init test-published-package \
  --namespace=default \
  --repository=porch-test \
  --workspace=published-v1 \
  --description="Test package for deletion"

porchctl rpkg propose porch-test.test-published-package.published-v1 --namespace=default
porchctl rpkg approve porch-test.test-published-package.published-v1 --namespace=default

Verify the PackageRevisions were created:

porchctl rpkg get --namespace=default

You should see an output similar to:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-draft-package.draft-v1 test-draft-package draft-v1 0 false Draft porch-test
porch-test.test-proposed-package.proposed-v1 test-proposed-package proposed-v1 0 false Proposed porch-test
porch-test.test-published-package.main test-published-package main -1 false Published porch-test
porch-test.test-published-package.published-v1 test-published-package published-v1 1 true Published porch-test

Step 2: Delete Draft PackageRevisions#

Draft PackageRevisions can be deleted immediately without any approval process:

porchctl rpkg del porch-test.test-draft-package.draft-v1 --namespace=default

What this does:

  • Immediately removes the Draft PackageRevision
  • Deletes the corresponding Git branch (draft/draft-v1)
  • No approval or confirmation required

Verify the deletion:

porchctl rpkg get --namespace=default

The Draft PackageRevision should no longer appear in the list:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-proposed-package.proposed-v1 test-proposed-package proposed-v1 0 false Proposed porch-test
porch-test.test-published-package.main test-published-package main -1 false Published porch-test
porch-test.test-published-package.published-v1 test-published-package published-v1 1 true Published porch-test

Step 3: Delete Proposed PackageRevisions#

Proposed PackageRevisions can also be deleted directly:

porchctl rpkg del porch-test.test-proposed-package.proposed-v1 --namespace=default

What this does:

  • Immediately removes the Proposed PackageRevision
  • Deletes the corresponding Git branch (proposed/proposed-v1)
  • No approval process required

Verify the deletion:

porchctl rpkg get --namespace=default

The Proposed PackageRevision should no longer appear in the list:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-published-package.main test-published-package main -1 false Published porch-test
porch-test.test-published-package.published-v1 test-published-package published-v1 1 true Published porch-test

Step 4: Propose Published PackageRevision for Deletion#

Published PackageRevisions cannot be deleted directly. You must first propose them for deletion:

porchctl rpkg propose-delete porch-test.test-published-package.published-v1 --namespace=default

What this does:

  • Changes the PackageRevision lifecycle from Published to DeletionProposed
  • Signals that the PackageRevision should be deleted
  • Requires approval before actual deletion occurs

Verify the state change:

porchctl rpkg get porch-test.test-published-package.published-v1 --namespace=default

The lifecycle should now show DeletionProposed:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-published-package.main test-published-package main -1 false Published porch-test
porch-test.test-published-package.published-v1 test-published-package published-v1 1 true DeletionProposed porch-test

Step 5a: Approve Deletion Proposal#

If you want to proceed with the deletion, approve the deletion proposal:

porchctl rpkg del porch-test.test-published-package.published-v1 --namespace=default

What this does:

  • Permanently deletes the PackageRevision
  • Removes the Git tag and any associated branches
  • Important: This cannot be undone once completed

Verify the deletion:

porchctl rpkg get --namespace=default

The published PackageRevision should no longer exist, but the main branch-tracking PackageRevision remains:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-published-package.main test-published-package main -1 false Published porch-test

Step 5b: Reject Deletion Proposal (Alternative)#

If you decide not to delete the PackageRevision, you can reject the deletion proposal:

# First, let's create another Published PackageRevision for this example
porchctl rpkg init test-reject-delete \
  --namespace=default \
  --repository=porch-test \
  --workspace=reject-v1 \
  --description="Test package for rejection"

porchctl rpkg propose porch-test.test-reject-delete.reject-v1 --namespace=default
porchctl rpkg approve porch-test.test-reject-delete.reject-v1 --namespace=default

# Propose it for deletion
porchctl rpkg propose-delete porch-test.test-reject-delete.reject-v1 --namespace=default

# Now reject the deletion proposal
porchctl rpkg reject porch-test.test-reject-delete.reject-v1 --namespace=default

What this does:

  • Changes lifecycle from DeletionProposed back to Published
  • PackageRevision returns to normal published state
  • The package can be used again normally

Verify the state change:

porchctl rpkg get porch-test.test-reject-delete.reject-v1 --namespace=default

The lifecycle should be back to Published:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-reject-delete.reject-v1 test-reject-delete reject-v1 1 true Published porch-test

Batch Deletion Operations#

You can delete multiple PackageRevisions with a single command:

Delete multiple Draft/Proposed PackageRevisions:

porchctl rpkg del package1 package2 package3 --namespace=default

Propose multiple Published PackageRevisions for deletion:

porchctl rpkg propose-delete package1 package2 package3 --namespace=default

Approve multiple deletion proposals:

porchctl rpkg del package1 package2 package3 --namespace=default

Deletion Workflow Summary#

The complete deletion workflow depends on the PackageRevision lifecycle state:

Loading diagram...

Safety Considerations#

Published PackageRevision Protection:

  • Two-step deletion process prevents accidental removal
  • Deletion proposals can be reviewed before approval
  • Rejected proposals restore the PackageRevision to Published state

Git Repository Impact:

  • Draft/Proposed deletions remove Git branches
  • Published deletions remove Git tags and references
  • Deletion is permanent and cannot be undone

Upstream Reference Considerations:

  • Upstream PackageRevisions cannot be deleted while downstream PackageRevisions reference them
  • Delete downstream PackageRevisions first, then you can delete the upstream PackageRevisions
  • The error message identifies which downstream PackageRevision is blocking deletion
  • Consider the impact on deployed workloads

Troubleshooting#

Cannot delete Published PackageRevision directly:

Error: cannot delete published package revision directly, use propose-delete first
  • Use porchctl rpkg propose-delete first, then porchctl rpkg del

PackageRevision not found:

  • Verify the exact PackageRevision name with the porchctl rpkg get --namespace=default command
  • Check you're using the correct namespace
  • Ensure the PackageRevision hasn't already been deleted

Permission denied:

  • Check RBAC permissions with the kubectl auth can-i delete packagerevisions -n default command
  • Verify your service account has proper deletion roles

Cannot delete upstream PackageRevision:

Error from server (Forbidden): cannot delete package revision, it is referenced as upstream by: <downstream-packagerevision-name>
  • See "Upstream Reference Considerations" in Safety Considerations above
  • Delete the downstream PackageRevision first, then retry

Deletion proposal stuck:

  • Check the PackageRevision status with the porchctl rpkg get <name> -o yaml command
  • Look for conditions that might prevent deletion
  • Ensure no other processes are modifying the PackageRevision

Complete Cleanup#

After deleting PackageRevisions, you may notice "main" branch-tracking PackageRevisions still exist. These are automatically created by Porch when packages are published and must be deleted separately.

{{% alert title="Important" color="warning" %}}
Main branch-tracking PackageRevisions (with workspace name "main" and revision "-1") are managed automatically by Porch. Do not modify, propose, approve, or otherwise interact with them except for deletion after all regular PackageRevisions of that specific package have been removed.
{{% /alert %}}

Check for remaining PackageRevisions:

porchctl rpkg get --namespace=default

You might see an output like:

NAME PACKAGE WORKSPACENAME REVISION LATEST LIFECYCLE REPOSITORY
porch-test.test-published-package.main test-published-package main -1 false Published porch-test
porch-test.test-reject-delete.main test-reject-delete main -1 false Published porch-test

Delete the main branch-tracking PackageRevisions:

# Propose deletion of main branch PackageRevisions
porchctl rpkg propose-delete porch-test.test-published-package.main --namespace=default
porchctl rpkg propose-delete porch-test.test-reject-delete.main --namespace=default

# Approve the deletions
porchctl rpkg del porch-test.test-published-package.main --namespace=default
porchctl rpkg del porch-test.test-reject-delete.main --namespace=default

Verify complete cleanup:

porchctl rpkg get --namespace=default

All test PackageRevisions should now be removed.